Drucken von Grafiken
Drucken eines 2D- oder 3D-Diagramms.
Das Beispiel zum Drucken von Diagrammen zeigt, wie 2D- und 3D-Diagramme gedruckt oder als PDF exportiert werden können.
Ausführen des Beispiels
Zum Ausführen des Beispiels von Qt Creatorauszuführen, öffnen Sie den Modus Welcome und wählen Sie das Beispiel unter Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.
GraphPrinter-Klasse
Die Druckfunktionalität ist in der Klasse GraphPrinter
implementiert. Die Klasse stellt diese Funktionen zur Verfügung:
- Die Funktion
generatePDF
, die wie folgt funktioniert.- Richtet die PDF-Ausgabedatei ein.
Die Funktion instanziiert QPdfWriter mit einer "graph.pdf"-Datei, die auf den angegebenen Ordner zeigt. Die Funktion legt auch die Optionen für die exportierte PDF-Datei fest: Titel, Auflösung, Seitengröße und Ränder.
const QFile file = QFile(path.toLocalFile() + QStringLiteral("/graph.pdf")); QPdfWriter writer(file.fileName()); writer.setResolution(90); writer.setTitle("Graph"); writer.setPageSize(QPageSize(image.size())); writer.setPageMargins(QMarginsF(0, 0, 0, 0)); writer.newPage();
- Richtet die Bildverarbeitung ein.
Die Funktion erstellt eine QPainter mit Verweis auf die zuvor erstellte QPdfWriter.
Um sicherzustellen, dass das Diagramm korrekt gedruckt wird, wird es auf die Größe des Ansichtsfensters des Malers mit dem ursprünglichen Seitenverhältnis skaliert
Der Rendering-Hinweis des Painters wird auf verlustfreies Bildrendering gesetzt. Danach zeichnet die Funktion das Bild in die PDF-Datei.
Die Funktion gibt eine Statusmeldung zurück, die im Meldungsdialog der Anwendung angezeigt wird und den vollständigen Pfad zur exportierten Datei enthält.
- Richtet die PDF-Ausgabedatei ein.
- Die Funktion
getPrinters
gibt eine Liste der verfügbaren Drucker zurück.QStringList GraphPrinter::getPrinters() { return QPrinterInfo::availablePrinterNames(); }
- Die Funktion
print
, die wie die FunktiongeneratePDF
funktioniert, aber eine QPainter erstellt, die auf eine QPrinter-Instanz verweist:QString GraphPrinter::print(const QImage &image, const QString printerName) { QPrinterInfo printInfo = QPrinterInfo::printerInfo(printerName); if (printInfo.isNull()) return QLatin1String("%1 is not a valid printer").arg(printerName); QPrinter printer(printInfo, QPrinter::HighResolution); printer.setOutputFormat(QPrinter::NativeFormat); QPainter painter(&printer); const QImage finalImage = image.scaled(painter.viewport().size(), Qt::KeepAspectRatio); painter.setRenderHint(QPainter::LosslessImageRendering); painter.drawImage(finalImage.rect(), finalImage); return QLatin1String("Printed to %1").arg(printerName); }
Die Funktion gibt eine Statusmeldung zurück, die im Meldungsdialog der Anwendung angezeigt wird.
Einrichtung der Anwendung
Zusätzlich zum Code für die Einrichtung der Anwendung enthält die Datei main.cpp
Code, der eine neue Instanz der GraphPrinter-Klasse erzeugt und sie vom QML-Code aus erreichbar macht.
GraphPrinter graphPrinter; viewer.rootContext()->setContextProperty("graphPrinter", &graphPrinter);
Einrichten des Layouts und der Bilderfassung
Die 2D- und 3D-Diagramme werden in einem Stacklayout angeordnet. Benutzer können darin mit einer TabBar navigieren.
TabBar { id: tabBar anchors.left: parent.left anchors.right: parent.right TabButton { text: "2D Graph" implicitHeight: 48 icon.source: checked ? "flatten_square_fill.svg" : "flatten.svg" icon.height: 36 icon.width: 36 } TabButton { text: "3D Graph" implicitHeight: 48 icon.source: checked ? "box_left_fill.svg" : "box_left.svg" icon.height: 36 icon.width: 36 } } Frame { id: tabFrame anchors.left: parent.left anchors.right: parent.right anchors.top: tabBar.bottom anchors.bottom: parent.bottom StackLayout { id: stackLayout anchors.fill: parent currentIndex: tabBar.currentIndex Graph2D { id: linegraph } Graph3D { id: bargraph } } }
Die FolderDialog-Komponente wird verwendet, um einen Ordner zum Speichern der exportierten Datei auszuwählen. Diese Komponente hat keine visuelle Darstellung im Anwendungslayout, aber ihre API ist über die aktuelle QML-Datei zugänglich.
Die Schaltfläche ruft einen Ordnerdialog auf.
FolderDialog { id: dialog property bool folderset: false onAccepted: { folderset = true message.title = "Folder Set" message.text = "Folder set to " + selectedFolder.toString().replace(/^(file:\/{3})/, "") message.open() } } ... Button { id: setFolderButton ... onClicked: dialog.open() }
Für die Auswahl eines Druckers wird ein benutzerdefinierter Druckdialog erstellt, der über die Schaltfläche aufgerufen wird. Der Dialog ruft die Liste der verfügbaren Drucker ab und zeigt sie in einer Listenansicht an.
Dialog { id: printerDialog anchors.centerIn: parent contentHeight: printerListView.height contentWidth: printerListView.width title: qsTr("Available Printers") modal: true onOpened: { printerModel.clear() var printers = graphPrinter.getPrinters() printers.forEach((x, i) => printerModel.append({ "name": x })) } ... contentItem: Rectangle { id: printerItem height: printerListView.height width: printerListView.width color: mainView.item.theme.plotAreaBackgroundColor ListView { id: printerListView height: 100 width: 200 clip: true model: printerModel delegate: printerDelegate highlight: Rectangle { color: mainView.item.theme.grid.subColor } } }
Die Schaltfläche löst den PDF-Export aus, wenn bereits ein Ordner ausgewählt wurde.
Wenn entweder der PDF-Export oder der Druck ausgelöst wird, wird der folgende Code ausgeführt:
- Erfassen Sie ein Bild mit der Methode
grabToImage
. Das aktuelle Diagramm ist das Element des Stacklayouts am aktuellen Index. - In den Parametern
grabToImage
geben wir den Callback als FunktiongeneratePDF
oderprint
in der KlasseGraphPrinter
an.PDF-Export:
onPressed: { if (!dialog.folderset) { message.title = "No Folder Set" message.text = "Please select folder first" message.open() } else { mainView.prepareForPrint() mainView.item.grabToImage(function (result) { message.title = "Save PDF" message.text = "PDF saved to " + graphPrinter.generatePDF( dialog.currentFolder, result.image) message.open() }, mainView.outputsize) } } onReleased: { mainView.cleanAfterPrint() }
Drucken:
onAccepted: { var selectedPrinter = printerModel.get(printerListView.currentIndex) mainView.prepareForPrint() mainView.item.grabToImage(function (result) { message.title = "Print" message.text = graphPrinter.print(result.image, selectedPrinter.name) message.open() }, mainView.outputsize) } onClosed: { mainView.cleanAfterPrint() }
Für die Größe sorgt der Code dafür, dass das Bild mit der 4-fachen tatsächlichen Auflösung gerendert wird. Bei 3D-Diagrammen muss das Element auch für die Dauer des Drucks erweitert werden:
function prepareForPrint() { if (stackLayout.currentIndex === 1) { outputsize = Qt.size(bargraph.width * 4, bargraph.height * 4) // resize the bar graph to match the PDF output size item.width = outputsize.width item.height = outputsize.height } else { outputsize = Qt.size(linegraph.width * 4, linegraph.height * 4) } } function cleanAfterPrint() { if (stackLayout.currentIndex === 1) { // resize the bar graph back to the actual visual size item.width = mainView.width item.height = mainView.height } }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.