Update the visuals of the graphprinting example
Fixes: QTBUG-131427 Change-Id: I093e439e63f318c7562471a221b831bf3832bf68 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Alexei Cazacov <alexei.cazacov@qt.io> (cherry picked from commit479b31786a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commitfc3d22bd43)
|
|
@ -21,6 +21,9 @@ find_package(Qt6 COMPONENTS Gui)
|
|||
find_package(Qt6 COMPONENTS Quick)
|
||||
find_package(Qt6 COMPONENTS Quick3D)
|
||||
find_package(Qt6 COMPONENTS Graphs)
|
||||
find_package(Qt6 COMPONENTS PrintSupport)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.8)
|
||||
|
||||
qt_add_executable(graphprinting
|
||||
main.cpp
|
||||
|
|
@ -48,6 +51,17 @@ qt6_add_qml_module(graphprinting
|
|||
qml/graphprinting/main.qml
|
||||
qml/graphprinting/Graph2D.qml
|
||||
qml/graphprinting/Graph3D.qml
|
||||
RESOURCES
|
||||
qml/graphprinting/box_left.svg
|
||||
qml/graphprinting/box_left_fill.svg
|
||||
qml/graphprinting/documents.svg
|
||||
qml/graphprinting/documents_fill.svg
|
||||
qml/graphprinting/flatten.svg
|
||||
qml/graphprinting/flatten_square_fill.svg
|
||||
qml/graphprinting/folder.svg
|
||||
qml/graphprinting/folder_fill.svg
|
||||
qml/graphprinting/print.svg
|
||||
qml/graphprinting/print_fill.svg
|
||||
)
|
||||
|
||||
install(TARGETS graphprinting
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 29 KiB |
|
|
@ -8,7 +8,7 @@
|
|||
\title Graph Printing
|
||||
\ingroup qtgraphs_qmlexamples
|
||||
\ingroup qtgraphs_qmlexamples_3D
|
||||
\brief Printing a 2D or 3D Graph to a PDF.
|
||||
\brief Printing a 2D or 3D graph.
|
||||
|
||||
The \e {Graph Printing} example demonstrates how to print or export to PDF
|
||||
2D and 3D graphs.
|
||||
|
|
@ -23,39 +23,42 @@
|
|||
class exposes these functions:
|
||||
|
||||
\list
|
||||
|
||||
\li The \c generatePDF function, which works as follows.
|
||||
|
||||
\li The \c generatePDF function, which works as follows.
|
||||
\list
|
||||
\li Sets up the output PDF file.
|
||||
\li Sets up the output PDF file.
|
||||
|
||||
The function instantiates \l QPdfWriter with a "graph.pdf" file
|
||||
pointed in the specified folder. The function also specifies the
|
||||
options for the exported PDF file: title, resolution, page size,
|
||||
and margins.
|
||||
The function instantiates \l QPdfWriter with a "graph.pdf" file
|
||||
pointed in the specified folder. The function also specifies the
|
||||
options for the exported PDF file: \e title, \e resolution, \e {page size},
|
||||
and \e margins.
|
||||
|
||||
\snippet graphprinting/graphprinter.cpp 0
|
||||
\li Sets up image processing.
|
||||
\snippet graphprinting/graphprinter.cpp 0
|
||||
\li Sets up image processing.
|
||||
|
||||
The function creates a \l QPainter referring to the previously
|
||||
created \l QPdfWriter.
|
||||
The function creates a \l QPainter referring to the previously
|
||||
created \l QPdfWriter.
|
||||
|
||||
To ensure the graph is printed correctly, it is scaled to the
|
||||
painter's viewport size with the original aspect ratio.
|
||||
To ensure the graph is printed correctly, it is scaled to the
|
||||
painter's viewport size with the original aspect ratio
|
||||
|
||||
The painter's rendering hint is set to lossless image rendering.
|
||||
After this, the function draws the image to the PDF file.
|
||||
The painter's rendering hint is set to lossless image rendering.
|
||||
After this, the function draws the image to the PDF file.
|
||||
|
||||
\snippet graphprinting/graphprinter.cpp 1
|
||||
\snippet graphprinting/graphprinter.cpp 1
|
||||
\endlist
|
||||
\li The \c print function, which works like the \c generatePDF function,
|
||||
but creates a \l QPainter referring a \QPrinter instance:
|
||||
|
||||
\snippet graphprinting/graphprinter.cpp 2
|
||||
|
||||
The function returns a status message to be displayed in the application's
|
||||
message dialog, including the full path to the exported file.
|
||||
\li The \c getPrinters function returns a list of available printers.
|
||||
|
||||
\snippet graphprinting/graphprinter.cpp 3
|
||||
\li The \c print function, which works like the \c generatePDF function,
|
||||
but creates a \l QPainter referring a \l QPrinter instance:
|
||||
|
||||
\snippet graphprinting/graphprinter.cpp 2
|
||||
|
||||
The function returns a status message to be displayed in the application's
|
||||
message dialog.
|
||||
\endlist
|
||||
|
||||
\section1 Application setup
|
||||
|
|
@ -73,41 +76,48 @@
|
|||
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 0
|
||||
|
||||
The FolderDialog component is used to select a folder for saving an
|
||||
The FolderDialog component is used to select a folder for saving the
|
||||
exported file. This component has no visual representation in the
|
||||
application layout, but its API is accessible from the current QML file.
|
||||
|
||||
The Button invokes a folder dialog.
|
||||
The \inlineimage graphprinting/qml/graphprinting/folder.svg button invokes a folder dialog.
|
||||
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 1.1
|
||||
\dots
|
||||
\dots 0
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 1.2
|
||||
\dots
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 1.3
|
||||
|
||||
A custom printing dialog is created for selecting a printer.
|
||||
A custom printing dialog is created for selecting a printer, and is triggered
|
||||
with the \inlineimage graphprinting/qml/graphprinting/print.svg button.
|
||||
The Dialog retrieves the list of available printers and displays them in a
|
||||
list view.
|
||||
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 2.1
|
||||
\dots
|
||||
\dots 0
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 2.2
|
||||
|
||||
The \uicontrol {Save to PDF} button and \uicontrol {Print} button in the
|
||||
printing dialog run the following code:
|
||||
The \inlineimage graphprinting/qml/graphprinting/documents.svg button triggers the
|
||||
PDF export, if a folder has been already selected.
|
||||
|
||||
When either PDF export or printing is triggered, the following code is executed:
|
||||
|
||||
\list
|
||||
\li Capture an image using the \c grabToImage method.
|
||||
The current graph is the Stacklayout's item at the current index.
|
||||
\li In the \c grabToImage parameters, we specify the callback as the
|
||||
\c generatePDF or \c print function in the \c GraphPrinter class.
|
||||
\li Capture an image using the \c grabToImage method.
|
||||
The current graph is the Stacklayout's item at the current index.
|
||||
\li In the \c grabToImage parameters, we specify the callback as the
|
||||
\c generatePDF or \c print function in the \c GraphPrinter class.
|
||||
|
||||
For the size, the code makes the image render at a 7282 by 4096
|
||||
resolution. For 3D graphs, the item must also be expanded
|
||||
for the duration of printing.
|
||||
PDF export:
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 3.1
|
||||
|
||||
Print:
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 3.2
|
||||
|
||||
For the size, the code makes the image render at 4x the actual
|
||||
resolution. For 3D graphs, the item must also be expanded
|
||||
for the duration of printing:
|
||||
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 3.3
|
||||
\endlist
|
||||
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 3.1
|
||||
\dots
|
||||
\snippet graphprinting/qml/graphprinting/main.qml 3.2
|
||||
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
#include "graphprinter.h"
|
||||
#include <QtGui/qtransform.h>
|
||||
#include <QtPrintSupport>
|
||||
#include <QtPrintSupport/QtPrintSupport>
|
||||
|
||||
GraphPrinter::GraphPrinter(QObject *parent)
|
||||
: QObject(parent)
|
||||
|
|
@ -10,7 +10,7 @@ GraphPrinter::GraphPrinter(QObject *parent)
|
|||
|
||||
GraphPrinter::~GraphPrinter() {}
|
||||
|
||||
void GraphPrinter::generatePDF(const QUrl &path, const QImage &image)
|
||||
QString GraphPrinter::generatePDF(const QUrl &path, const QImage &image)
|
||||
{
|
||||
//! [0]
|
||||
const QFile file = QFile(path.toLocalFile() + QStringLiteral("/graph.pdf"));
|
||||
|
|
@ -30,17 +30,15 @@ void GraphPrinter::generatePDF(const QUrl &path, const QImage &image)
|
|||
painter.drawImage(finalImage.rect(), finalImage);
|
||||
//! [1]
|
||||
|
||||
qInfo("printed PDF to %ls", qUtf16Printable(file.fileName()));
|
||||
return file.fileName();
|
||||
}
|
||||
|
||||
//! [2]
|
||||
void GraphPrinter::print(const QImage &image, const QString printerName)
|
||||
QString GraphPrinter::print(const QImage &image, const QString printerName)
|
||||
{
|
||||
QPrinterInfo printInfo = QPrinterInfo::printerInfo(printerName);
|
||||
if (printInfo.isNull()) {
|
||||
qWarning("%ls is not a valid printer", qUtf16Printable(printerName));
|
||||
return;
|
||||
}
|
||||
if (printInfo.isNull())
|
||||
return QLatin1String("%1 is not a valid printer").arg(printerName);
|
||||
|
||||
QPrinter printer(printInfo, QPrinter::HighResolution);
|
||||
printer.setOutputFormat(QPrinter::NativeFormat);
|
||||
|
|
@ -50,7 +48,7 @@ void GraphPrinter::print(const QImage &image, const QString printerName)
|
|||
painter.setRenderHint(QPainter::LosslessImageRendering);
|
||||
painter.drawImage(finalImage.rect(), finalImage);
|
||||
|
||||
qInfo("printed image with %ls", qUtf16Printable(printerName));
|
||||
return QLatin1String("Printed to %1").arg(printerName);
|
||||
}
|
||||
//! [2]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ public:
|
|||
explicit GraphPrinter(QObject *parent = 0);
|
||||
~GraphPrinter() override;
|
||||
|
||||
Q_INVOKABLE void generatePDF(const QUrl &path, const QImage &image);
|
||||
Q_INVOKABLE void print(const QImage &image, const QString printerName);
|
||||
Q_INVOKABLE QString generatePDF(const QUrl &path, const QImage &image);
|
||||
Q_INVOKABLE QString print(const QImage &image, const QString printerName);
|
||||
Q_INVOKABLE QStringList getPrinters();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int main(int argc, char *argv[]) {
|
|||
viewer.setMinimumSize({1280, 720});
|
||||
viewer.setSource(QUrl("qrc:/qml/graphprinting/main.qml"));
|
||||
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
viewer.setColor("black");
|
||||
viewer.setColor("white");
|
||||
viewer.show();
|
||||
|
||||
return app.exec();
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ Rectangle {
|
|||
id: graphContainer
|
||||
width: 1280
|
||||
height: 720
|
||||
property alias theme: lines.theme
|
||||
|
||||
color: "white"
|
||||
|
||||
GraphsView {
|
||||
id: lines
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
theme: GraphsTheme {
|
||||
|
|
@ -20,6 +22,7 @@ Rectangle {
|
|||
labelTextColor: "black"
|
||||
plotAreaBackgroundColor: "white"
|
||||
backgroundColor: "white"
|
||||
colorScheme: Qt.Light
|
||||
}
|
||||
axisX: ValueAxis {
|
||||
max: 5
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ Item {
|
|||
id: graphContainer
|
||||
width: 1280
|
||||
height: 720
|
||||
property alias theme: bars.theme
|
||||
|
||||
Bars3D {
|
||||
id: bars
|
||||
anchors.fill: parent
|
||||
msaaSamples: 8
|
||||
cameraPreset: Graphs3D.CameraPreset.IsometricLeftHigh
|
||||
|
|
@ -20,6 +22,7 @@ Item {
|
|||
grid.mainColor: "black"
|
||||
labelFont.pointSize: 20
|
||||
labelBackgroundVisible: false
|
||||
colorScheme: Qt.Light
|
||||
}
|
||||
|
||||
Bar3DSeries {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 7.35407L4 16.6459L12 19.8459L20 16.6459V7.35407L12 4.15407L4 7.35407ZM2 16.6459V7.35407C2 6.53626 2.4979 5.80084 3.25722 5.49711L11.2572 2.29711C11.734 2.10639 12.266 2.10639 12.7428 2.29711L20.7428 5.49711C21.5021 5.80084 22 6.53626 22 7.35407V16.6459C22 17.4637 21.5021 18.1992 20.7428 18.5029L12.7428 21.7029C12.266 21.8936 11.734 21.8936 11.2572 21.7029L3.25722 18.5029C2.4979 18.1992 2 17.4637 2 16.6459Z" fill="#181818"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2903 10.2903L10.8761 11.7045L4 8.95407V11.3864V16.6459L11 19.4459L11 11.8284L10.8761 11.7045L12.2903 10.2903ZM2 16.6459V11.3864V8.95407C2 7.53914 3.42905 6.57162 4.74278 7.09711L11.6188 9.84754C11.8703 9.94813 12.0988 10.0988 12.2903 10.2903L12.4142 10.4142C12.7893 10.7893 13 11.298 13 11.8284V19.5434C13 19.8437 12.9301 20.1398 12.7958 20.4083C12.346 21.308 11.2817 21.7127 10.3478 21.3391L3.25722 18.5029C2.4979 18.1992 2 17.4637 2 16.6459Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 7.35407L4 16.6459L12 19.8459L20 16.6459V7.35407L12 4.15407L4 7.35407ZM2 16.6459V7.35407C2 6.53626 2.4979 5.80084 3.25722 5.49711L11.2572 2.29711C11.734 2.10639 12.266 2.10639 12.7428 2.29711L20.7428 5.49711C21.5021 5.80084 22 6.53626 22 7.35407V16.6459C22 17.4637 21.5021 18.1992 20.7428 18.5029L12.7428 21.7029C12.266 21.8936 11.734 21.8936 11.2572 21.7029L3.25722 18.5029C2.4979 18.1992 2 17.4637 2 16.6459Z" fill="#181818"/>
|
||||
<path d="M2 11.3864V16.6459C2 17.4637 2.4979 18.1992 3.25722 18.5029L10.3478 21.3391C11.2817 21.7127 12.346 21.308 12.7958 20.4083C12.9301 20.1398 13 19.8437 13 19.5434V11.8284C13 11.298 12.7893 10.7893 12.4142 10.4142L12.2903 10.2903C12.0988 10.0988 11.8703 9.94813 11.6188 9.84754L4.74278 7.09711C3.42905 6.57162 2 7.53914 2 8.95407V11.3864Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 945 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 4L6 20H18L18 8.40053L13.4737 4H6ZM4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8.40053C20 7.86033 19.7815 7.3431 19.3942 6.96654L14.8679 2.56601C14.4946 2.20306 13.9944 2 13.4737 2H6C4.89543 2 4 2.89543 4 4Z" fill="#181818"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 3.70711V7C13 8.10457 13.8954 9 15 9H18.2929C18.6834 9 19 8.68342 19 8.29289C19 8.10536 18.9255 7.9255 18.7929 7.79289L14.2071 3.20711C14.0745 3.0745 13.8946 3 13.7071 3C13.3166 3 13 3.31658 13 3.70711ZM8 11C7.44772 11 7 11.4477 7 12C7 12.5523 7.44772 13 8 13H16C16.5523 13 17 12.5523 17 12C17 11.4477 16.5523 11 16 11H8ZM8 14C7.44772 14 7 14.4477 7 15C7 15.5523 7.44772 16 8 16H16C16.5523 16 17 15.5523 17 15C17 14.4477 16.5523 14 16 14H8ZM7 18C7 17.4477 7.44772 17 8 17H13C13.5523 17 14 17.4477 14 18C14 18.5523 13.5523 19 13 19H8C7.44772 19 7 18.5523 7 18Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 4V20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V8.40053C20 7.86033 19.7815 7.3431 19.3942 6.96654L14.8679 2.56601C14.4946 2.20306 13.9944 2 13.4737 2H6C4.89543 2 4 2.89543 4 4ZM8 11C7.44772 11 7 11.4477 7 12C7 12.5523 7.44772 13 8 13H16C16.5523 13 17 12.5523 17 12C17 11.4477 16.5523 11 16 11H8ZM7 15C7 14.4477 7.44772 14 8 14H16C16.5523 14 17 14.4477 17 15C17 15.5523 16.5523 16 16 16H8C7.44772 16 7 15.5523 7 15ZM8 17C7.44772 17 7 17.4477 7 18C7 18.5523 7.44772 19 8 19H13C13.5523 19 14 18.5523 14 18C14 17.4477 13.5523 17 13 17H8Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 721 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 4H4V20H20V4ZM4 2C2.89543 2 2 2.89543 2 4V20C2 21.1046 2.89543 22 4 22H20C21.1046 22 22 21.1046 22 20V4C22 2.89543 21.1046 2 20 2H4Z" fill="#181818"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.9042 7.573C22.1401 8.0724 21.9264 8.66843 21.427 8.90426L3.427 17.4043C2.92759 17.6401 2.33157 17.4264 2.09574 16.927C1.85991 16.4276 2.07358 15.8316 2.57298 15.5958L20.573 7.09576C21.0724 6.85993 21.6684 7.0736 21.9042 7.573Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 604 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM2 4C2 2.89543 2.89543 2 4 2H20C21.1046 2 22 2.89543 22 4V20C22 21.1046 21.1046 22 20 22H4C2.89543 22 2 21.1046 2 20V4ZM20 4V7.39559L19.5756 7.59454L4 14.8956V4H20ZM4.42443 16.9055L4 17.1044V20H20V9.60441L4.42443 16.9055Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 511 B |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0968 6H5C4.44772 6 4 6.44772 4 7V17C4 17.5523 4.44772 18 5 18H19C19.5523 18 20 17.5523 20 17V10C20 9.44772 19.5523 9 19 9H13.0968C11.9388 9 11 8.06124 11 6.90323C11 6.40439 10.5956 6 10.0968 6ZM10.0968 4H5C3.34315 4 2 5.34315 2 7V17C2 18.6569 3.34315 20 5 20H19C20.6569 20 22 18.6569 22 17V10C22 8.34315 20.6569 7 19 7H13.0968C13.0433 7 13 6.95667 13 6.90323C13 5.29982 11.7002 4 10.0968 4Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 565 B |
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0968 6H5C4.44772 6 4 6.44772 4 7V17C4 17.5523 4.44772 18 5 18H19C19.5523 18 20 17.5523 20 17V10C20 9.44772 19.5523 9 19 9H13.0968C11.9388 9 11 8.06124 11 6.90323C11 6.40439 10.5956 6 10.0968 6ZM10.0968 4H5C3.34315 4 2 5.34315 2 7V17C2 18.6569 3.34315 20 5 20H19C20.6569 20 22 18.6569 22 17V10C22 8.34315 20.6569 7 19 7H13.0968C13.0433 7 13 6.95667 13 6.90323C13 5.29982 11.7002 4 10.0968 4Z" fill="#181818"/>
|
||||
<path d="M5 4H10.0968C11.7002 4 13 5.29982 13 6.90323C13 6.95667 13.0433 7 13.0968 7H19C20.6569 7 22 8.34315 22 10V17C22 18.6569 20.6569 20 19 20H5C3.34315 20 2 18.6569 2 17V7C2 5.34315 3.34315 4 5 4Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 784 B |
|
|
@ -1,151 +1,215 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.Fusion
|
||||
import QtQuick.Dialogs
|
||||
|
||||
Item {
|
||||
Rectangle {
|
||||
id: mainView
|
||||
width: 1280
|
||||
height: 720
|
||||
color: Application.styleHints.colorScheme === Qt.Dark ? "darkgray" : "lightgray"
|
||||
|
||||
//! [0]
|
||||
TabBar {
|
||||
id: tabBar
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
TabButton {
|
||||
text: "2D Graph"
|
||||
implicitHeight: 50
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: "3D Graph"
|
||||
implicitHeight: 50
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackLayout
|
||||
anchors.top: tabBar.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
currentIndex: tabBar.currentIndex
|
||||
|
||||
Graph2D {}
|
||||
|
||||
Graph3D {}
|
||||
}
|
||||
//! [0]
|
||||
property var item: stackLayout.itemAt(stackLayout.currentIndex)
|
||||
property var outputsize: Qt.size(linegraph.width * 4, linegraph.height * 4)
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
anchors.topMargin: 5
|
||||
anchors.bottomMargin: 5
|
||||
spacing: 5
|
||||
|
||||
//! [1.2]
|
||||
Button {
|
||||
id: setFolderButton
|
||||
onClicked: dialog.open()
|
||||
text: "Set save location"
|
||||
Layout.margins: 5
|
||||
}
|
||||
//! [1.2]
|
||||
//! [3.1]
|
||||
Button {
|
||||
id: captureButton
|
||||
text: "Save to PDF"
|
||||
Layout.margins: 5
|
||||
property var item: stackLayout.itemAt(stackLayout.currentIndex)
|
||||
GroupBox {
|
||||
id: groupBox
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
title: qsTr("Printing and exporting")
|
||||
|
||||
onPressed: {
|
||||
if (stackLayout.currentIndex === 1) {
|
||||
item.width = 7282
|
||||
item.height = 4096
|
||||
ColumnLayout {
|
||||
id: buttonLayout
|
||||
spacing: 0
|
||||
uniformCellSizes: true
|
||||
//! [1.2]
|
||||
Button {
|
||||
id: setFolderButton
|
||||
//! [1.2]
|
||||
text: qsTr("Set save location")
|
||||
flat: true
|
||||
|
||||
icon.source: pressed ? "folder_fill.svg" : "folder.svg"
|
||||
icon.height: 36
|
||||
icon.width: 36
|
||||
//! [1.3]
|
||||
onClicked: dialog.open()
|
||||
}
|
||||
item.grabToImage(function(result) {
|
||||
graphPrinter.generatePDF(dialog.currentFolder, result.image)
|
||||
}, Qt.size(7282, 4096))
|
||||
}
|
||||
//! [1.3]
|
||||
Button {
|
||||
id: captureButton
|
||||
text: qsTr("Save to PDF")
|
||||
flat: true
|
||||
|
||||
onReleased: {
|
||||
if (stackLayout.currentIndex === 1) {
|
||||
item.width = mainView.width
|
||||
item.height = mainView.height
|
||||
icon.source: pressed ? "documents_fill.svg" : "documents.svg"
|
||||
icon.height: 36
|
||||
icon.width: 36
|
||||
|
||||
//! [3.1]
|
||||
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()
|
||||
}
|
||||
//! [3.1]
|
||||
}
|
||||
|
||||
Button {
|
||||
id: printButton
|
||||
text: qsTr("Send to printer")
|
||||
flat: true
|
||||
|
||||
icon.source: pressed ? "print_fill.svg" : "print.svg"
|
||||
icon.height: 36
|
||||
icon.width: 36
|
||||
|
||||
onPressed: printerDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [3.1]
|
||||
|
||||
Button {
|
||||
id: printButton
|
||||
text: "Send to printer"
|
||||
Layout.margins: 5
|
||||
onPressed: printerDialog.open()
|
||||
Item {
|
||||
id: tabGroup
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
//! [0]
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [0]
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: message
|
||||
}
|
||||
|
||||
//! [1.1]
|
||||
FolderDialog {
|
||||
id: dialog
|
||||
onAccepted: console.log("Saving to " + currentFolder)
|
||||
property bool folderset: false
|
||||
onAccepted: {
|
||||
folderset = true
|
||||
message.title = "Folder Set"
|
||||
message.text = "Folder set to " + selectedFolder.toString().replace(/^(file:\/{3})/, "")
|
||||
message.open()
|
||||
}
|
||||
}
|
||||
//! [1.1]
|
||||
|
||||
//! [2.1]
|
||||
Dialog {
|
||||
id: printerDialog
|
||||
x: parent.width * 0.5 - width * 0.5
|
||||
y: parent.height * 0.5;
|
||||
contentHeight: 200
|
||||
contentWidth: 200
|
||||
anchors.centerIn: parent
|
||||
contentHeight: printerListView.height
|
||||
contentWidth: printerListView.width
|
||||
|
||||
title: qsTr("Available printers")
|
||||
title: qsTr("Available Printers")
|
||||
modal: true
|
||||
|
||||
property var item: stackLayout.itemAt(stackLayout.currentIndex)
|
||||
|
||||
onOpened: {
|
||||
printerModel.clear()
|
||||
var printers = graphPrinter.getPrinters()
|
||||
printers.forEach((x,i) =>
|
||||
printerModel.append({"name": x}))
|
||||
printers.forEach((x, i) => printerModel.append({
|
||||
"name": x
|
||||
}))
|
||||
}
|
||||
//! [2.1]
|
||||
|
||||
//! [3.2]
|
||||
onAccepted: {
|
||||
var selectedPrinter = printerModel.get(printerListView.currentIndex)
|
||||
if (stackLayout.currentIndex === 1) {
|
||||
item.width = 7282
|
||||
item.height = 4096
|
||||
}
|
||||
item.grabToImage(function(result) {
|
||||
graphPrinter.print(result.image, selectedPrinter.name)
|
||||
}, Qt.size(7282, 4096))
|
||||
mainView.prepareForPrint()
|
||||
mainView.item.grabToImage(function (result) {
|
||||
message.title = "Print"
|
||||
message.text = graphPrinter.print(result.image,
|
||||
selectedPrinter.name)
|
||||
message.open()
|
||||
}, mainView.outputsize)
|
||||
}
|
||||
onClosed: {
|
||||
if (stackLayout.currentIndex === 1) {
|
||||
item.width = mainView.width
|
||||
item.height = mainView.height
|
||||
}
|
||||
}
|
||||
//! [3.2]
|
||||
|
||||
onClosed: {
|
||||
mainView.cleanAfterPrint()
|
||||
}
|
||||
|
||||
//! [3.2]
|
||||
Component {
|
||||
id : printerDelegate
|
||||
id: printerDelegate
|
||||
Rectangle {
|
||||
width: 200; height: 40
|
||||
width: 198
|
||||
height: 25
|
||||
color: "transparent"
|
||||
border.color: "black"
|
||||
border.color: mainView.item.theme.grid.mainColor
|
||||
clip: true
|
||||
|
||||
Text {
|
||||
padding: 5
|
||||
text: qsTr("<b>%1</b>").arg(name)
|
||||
color: "white"
|
||||
color: mainView.item.theme.labelTextColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
|
@ -156,23 +220,27 @@ Item {
|
|||
}
|
||||
|
||||
//! [2.2]
|
||||
contentItem: Item {
|
||||
contentItem: Rectangle {
|
||||
id: printerItem
|
||||
height: 200
|
||||
width: parent.width
|
||||
height: printerListView.height
|
||||
width: printerListView.width
|
||||
color: mainView.item.theme.plotAreaBackgroundColor
|
||||
|
||||
ListView {
|
||||
id: printerListView
|
||||
height: 200
|
||||
height: 100
|
||||
width: 200
|
||||
clip: true
|
||||
|
||||
model: printerModel
|
||||
delegate: printerDelegate
|
||||
highlight: Rectangle {color: "darkgrey"}
|
||||
highlight: Rectangle {
|
||||
color: mainView.item.theme.grid.subColor
|
||||
}
|
||||
}
|
||||
}
|
||||
//! [2.2]
|
||||
|
||||
//! [2.2]
|
||||
footer: DialogButtonBox {
|
||||
Button {
|
||||
text: "Print"
|
||||
|
|
@ -185,6 +253,25 @@ Item {
|
|||
ListModel {
|
||||
id: printerModel
|
||||
}
|
||||
|
||||
//! [3.3]
|
||||
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
|
||||
}
|
||||
}
|
||||
//! [3.3]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="File / print">
|
||||
<path id="Layer01" fill-rule="evenodd" clip-rule="evenodd" d="M7 2C6.44772 2 6 2.44772 6 3V6H5C3.34315 6 2 7.34315 2 9V17C2 17.5523 2.44772 18 3 18H6V16H4V9C4 8.44772 4.44772 8 5 8H7H17H19C19.5523 8 20 8.44772 20 9V16H18V18H21C21.5523 18 22 17.5523 22 17V9C22 7.34315 20.6569 6 19 6H18V3C18 2.44772 17.5523 2 17 2H7ZM16 6V4H8V6H16ZM19 10C19 10.5523 18.5523 11 18 11C17.4477 11 17 10.5523 17 10C17 9.44772 17.4477 9 18 9C18.5523 9 19 9.44772 19 10Z" fill="#181818"/>
|
||||
<path id="Layer02" fill-rule="evenodd" clip-rule="evenodd" d="M6 13C6 12.4477 6.44772 12 7 12H17C17.5523 12 18 12.4477 18 13V21C18 21.5523 17.5523 22 17 22H7C6.44772 22 6 21.5523 6 21V13ZM8 14V20H16V14H8ZM8.5 18C8.5 17.7239 8.72386 17.5 9 17.5H15C15.2761 17.5 15.5 17.7239 15.5 18C15.5 18.2761 15.2761 18.5 15 18.5H9C8.72386 18.5 8.5 18.2761 8.5 18ZM9 15.5C8.72386 15.5 8.5 15.7239 8.5 16C8.5 16.2761 8.72386 16.5 9 16.5H15C15.2761 16.5 15.5 16.2761 15.5 16C15.5 15.7239 15.2761 15.5 15 15.5H9Z" fill="#181818"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 6V4H16V6H8ZM6 6V3C6 2.44772 6.44772 2 7 2H17C17.5523 2 18 2.44772 18 3V6H19C20.6569 6 22 7.34315 22 9V17C22 17.5523 21.5523 18 21 18H19V21C19 22.1046 18.1046 23 17 23H7C5.89543 23 5 22.1046 5 21V18H3C2.44772 18 2 17.5523 2 17V9C2 7.34315 3.34315 6 5 6H6ZM6 18V20C6 21.1046 6.89543 22 8 22H16C17.1046 22 18 21.1046 18 20V18V14C18 12.8954 17.1046 12 16 12H8C6.89543 12 6 12.8954 6 14V18ZM18 11C18.5523 11 19 10.5523 19 10C19 9.44772 18.5523 9 18 9C17.4477 9 17 9.44772 17 10C17 10.5523 17.4477 11 18 11ZM17 14C17 13.4477 16.5523 13 16 13H8C7.44772 13 7 13.4477 7 14V20C7 20.5523 7.44772 21 8 21H16C16.5523 21 17 20.5523 17 20V14ZM9 15.5C8.72386 15.5 8.5 15.7239 8.5 16C8.5 16.2761 8.72386 16.5 9 16.5H15C15.2761 16.5 15.5 16.2761 15.5 16C15.5 15.7239 15.2761 15.5 15 15.5H9ZM9 17.5C8.72386 17.5 8.5 17.7239 8.5 18C8.5 18.2761 8.72386 18.5 9 18.5H15C15.2761 18.5 15.5 18.2761 15.5 18C15.5 17.7239 15.2761 17.5 15 17.5H9Z" fill="#181818"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |