Kapitel 24. Druckausgabe

Jeder Entwickler weiß, wie unerwartet komplex das Drucken wird, wenn das Layout „verrutscht”, Schriftarten anders aussehen und derselbe Code sich auf verschiedenen Plattformen unterschiedlich verhält. Hatten Sie schon mal das Gefühl, dass Druckausgabe eine eigene Welt mit ihren Fallen ist?

Dieses Kapitel zeigt Schritt für Schritt, warum Drucken in Qt tatsächlich einfacher ist als gedacht, und wo genau die Schlüsselidee liegt, die bis zu 80 % der typischen Probleme beseitigt. Hier entdecken Sie, wie ein einheitlicher Zeichenmechanismus die Duplizierung von Logik vermeidet.

Es wird gezeigt, wie derselbe Code für Bildschirm, Drucker und PDF funktioniert, welche 5 Schlüsseleinstellungen tatsächlich das Ergebnis beeinflussen und wie man Seiten, Ausrichtung und Skalierung korrekt verwaltet — ohne „Magic Numbers” und Workaround-Lösungen.

Nach diesem Kapitel ändert sich die Herangehensweise ans Drucken für immer: von chaotischen Experimenten zu kontrolliertem und vorhersagbarem Ergebnis. Es zu überspringen bedeutet, bereits gelöste Probleme weiter zu lösen.

Das Kapitel enthält Code-Beispiele, die sofort einsatzbereit sind.

Selbsttest zum Kapitel

Warum ist die Klasse QPrinter von QPaintDevice abgeleitet und wie vereinfacht das die Aufgabe des Entwicklers?Antwort
Richtige Antwort: Dank der Vererbung von QPaintDevice funktioniert Drucken wie normales Zeichnen — für die Ausgabe auf den Drucker werden dieselben QPainter-Methoden verwendet wie für den Bildschirm, wodurch die Notwendigkeit entfällt, eine separate API für das Drucken zu erlernen.
Warum muss im Projektfile das Modul QtPrintSupport explizit eingebunden werden?Antwort
Richtige Antwort: Die Druckklassen (QPrinter, QPrintDialog) befinden sich im separaten Modul QtPrintSupport, das nicht standardmäßig eingebunden ist, daher muss es über QT += printsupport oder target_link_libraries in CMake hinzugefügt werden.
Was passiert, wenn man einen leeren String an die Methode setOutputFileName() übergibt?Antwort
Richtige Antwort: Das System ignoriert die Umleitung der Ausgabe in eine Datei, und der Druck erfolgt auf das physische Druckgerät statt in einer Datei gespeichert zu werden.
Wie leitet man die Druckausgabe in eine PDF-Datei um, anstatt sie an den Drucker zu senden?Antwort
Richtige Antwort: Man muss die Methode setOutputFormat() mit dem Wert QPrinter::PdfFormat aufrufen und den Namen der Ausgabedatei über setOutputFileName() angeben — dies erstellt ein PDF-Dokument anstelle der Sendung an einen physischen Drucker.
Warum muss die Methode viewport() vor Beginn des Zeichnens beim Drucken aufgerufen werden?Antwort
Richtige Antwort: Die meisten Drucker können nicht die gesamte Blattfläche zum Drucken nutzen, daher gibt viewport() den für das Drucken verfügbaren rechteckigen Bereich zurück, wodurch eine Ausgabe außerhalb der druckbaren Zone vermieden wird.
Wozu dient die Methode setFontEmbeddingEnabled() und wann sollte sie verwendet werden?Antwort
Richtige Antwort: Die Methode bettet Schriftarten in das Dokument ein und garantiert, dass die Datei alle erforderlichen Schriftarten enthält; dies ist nützlich bei der Verwendung von Dateien auf anderen Plattformen, wo die benötigten Schriftarten möglicherweise nicht installiert sind.
Welche Methodenkombination muss verwendet werden, um Querformat einzustellen und drei Kopien zu drucken?Antwort
Richtige Antwort: setPageOrientation(QPageLayout::Landscape) für Querformat und setCopyCount(3) zur Festlegung der Anzahl der Kopien.
Warum wird im Codebeispiel std::unique_ptr für das QPrinter-Objekt verwendet?Antwort
Richtige Antwort: Dies entspricht dem RAII-Prinzip und gibt automatisch Speicher bei Objektzerstörung frei, was die Notwendigkeit expliziter Löschung im Destruktor beseitigt und das Risiko von Memory Leaks reduziert.
Warum wird ein Zeiger auf das übergeordnete Widget im zweiten Parameter des QPrintDialog-Konstruktors übergeben?Antwort
Richtige Antwort: Dies ermöglicht es dem Dialogfenster, relativ zum Hauptfenster der Anwendung zentriert zu werden, was eine bessere Benutzernavigation gewährleistet.
Wie berechnet man die Anzahl der zu druckenden Seiten, nachdem der Benutzer einen Bereich im Druckdialog ausgewählt hat?Antwort
Richtige Antwort: Man muss fromPage() von toPage() subtrahieren und eins addieren: int nPages = dlg.toPage() – dlg.fromPage() + 1.
Was passiert, wenn man vergisst, newPage() beim Drucken eines mehrseitigen Dokuments aufzurufen?Antwort
Richtige Antwort: Der gesamte Inhalt wird auf einer Seite übereinander gezeichnet, da newPage() erforderlich ist, um eine neue Seite im Druckauftrag zu erstellen, bevor mit dem Zeichnen fortgefahren wird.
Welche drei Schlüsselmethoden der Klasse QPrinter ermöglichen die Steuerung von Farbigkeit, Papiergröße und Seitenbereich?Antwort
Richtige Antwort: setColorMode() zur Steuerung des Farb-/Schwarzweiß-Modus, setPageSize() zur Änderung der Papiergröße über ein QPageSize-Objekt, und setFromTo() zur Festlegung des zu druckenden Seitenbereichs.

Praktische Aufgaben

Einfaches Level

Anwendung zum Drucken von Visitenkarten
Erstellen Sie eine Qt-Anwendung mit einem Button „Visitenkarte drucken”, die eine einfache Visitenkarte mit Ihrem Namen, Position und Kontaktinformationen ausgibt. Verwenden Sie verschiedene Schriftgrößen und Farben für die Textgestaltung. Fügen Sie einen dekorativen Rahmen um die Visitenkarte hinzu.
Hinweise: Binden Sie das QtPrintSupport-Modul im Projektfile ein. Erstellen Sie einen QPrinter und verwenden Sie QPainter zum Zeichnen darauf. Nutzen Sie die Methode viewport() zum Abrufen des Druckbereichs. Verwenden Sie drawRect() für den Rahmen, setFont() für verschiedene Textgrößen und drawText() mit Ausrichtungsflags. Öffnen Sie den Druckdialog über QPrintDialog vor der Ausgabe.

Mittleres Level

Berichtsgenerator mit Ausgabeformatwahl
Entwickeln Sie eine Anwendung, die einen einfachen Bericht mit Überschrift, Erstellungsdatum, Datentabelle (3-4 Zeilen) und Zusammenfassung erstellt. Der Benutzer soll wählen können, wohin der Bericht ausgegeben wird: an den Drucker oder als PDF-Datei gespeichert. Implementieren Sie einen Modusschalter (Radiobuttons) und programmatische Einstellung der Seitenausrichtung auf Querformat für eine bequemere Tabellenplatzierung.
Hinweise: Verwenden Sie QRadioButton zur Auswahl des Ausgabemodus. Bei PDF-Auswahl nutzen Sie setOutputFormat(QPrinter::PdfFormat) und setOutputFileName(). Für Querformat verwenden Sie setPageOrientation(QPageLayout::Landscape). Zeichnen Sie die Tabelle mit drawLine() und drawText(). Erstellen Sie eine separate Methode zum Zeichnen des Berichts, die sowohl für Druck als auch für PDF verwendet werden kann.

Schwieriges Level

Mehrseitiges Fotoalbum mit Layout
Erstellen Sie eine Anwendung zum Drucken eines Fotoalbums: Der Benutzer wählt mehrere Bilder (mindestens 6) aus, und das Programm platziert automatisch 2 Bilder pro Seite mit Beschriftungen darunter. Auf der ersten Seite soll ein Cover mit Albumtitel und Erstellungsdatum sein. Implementieren Sie Bildskalierung unter Beibehaltung der Proportionen, fügen Sie Seitennummerierung in der Fußzeile hinzu. Sehen Sie die Möglichkeit vor, in Farbe oder Schwarzweiß zu drucken.
Hinweise: Verwenden Sie QFileDialog zur Auswahl mehrerer Bilder. Laden Sie diese über QImage. Organisieren Sie eine Schleife über Seiten mit Aufruf von newPage() für jede neue Seite nach der ersten. Skalieren Sie Bilder mit der Methode scaled() und dem Flag Qt::KeepAspectRatio. Berechnen Sie Positionen für die Platzierung von zwei Bildern auf der Seite (obere und untere Hälfte unter Berücksichtigung von Abständen). Für das Cover verwenden Sie große zentrierte Schrift. Für Seitennummerierung verwenden Sie einen Zähler in der Schleife und drawText() in der Seitenecke. Fügen Sie eine QCheckBox zur Auswahl Farb-/Schwarzweiß-Modus hinzu und wenden Sie setColorMode() an.

💬 Beteiligen Sie sich an der Diskussion!

Druckausgabe in Qt verstanden? Fragen zur QPrinter-Konfiguration oder Organisation mehrseitigen Drucks aufgetaucht?

Teilen Sie Ihre Erfahrungen mit PDF-Generierung, berichten Sie von unkonventionellen Druckaufgaben oder helfen Sie anderen Lesern, das Kapitelmaterial zu verstehen!

Leave a Reply

Your email address will not be published. Required fields are marked *