From cd1ddd3450e2e9d708cecd814cc356a44fe0282a Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Fri, 27 Aug 2021 13:24:42 +0200 Subject: Fix crash in PrintMe example Connecting the same lambda slot multiple times to QWebEngineView::printFinished causes crash. Fix this by a minor refactoration and adjust documentation. Task-number: QTBUG-95339 Change-Id: I03b6a1ff6244c80073248182a905d8d664fdd326 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit e3679c1a8316b70fb6b8a0f85fdd06443de8b409) Reviewed-by: Qt Cherry-pick Bot --- .../webenginewidgets/printme/doc/src/printme.qdoc | 21 ++++++++++------ examples/webenginewidgets/printme/printhandler.cpp | 29 ++++++++++------------ examples/webenginewidgets/printme/printhandler.h | 5 ++++ 3 files changed, 32 insertions(+), 23 deletions(-) (limited to 'examples') diff --git a/examples/webenginewidgets/printme/doc/src/printme.qdoc b/examples/webenginewidgets/printme/doc/src/printme.qdoc index 1ba37d0c3..f17fae1a8 100644 --- a/examples/webenginewidgets/printme/doc/src/printme.qdoc +++ b/examples/webenginewidgets/printme/doc/src/printme.qdoc @@ -66,8 +66,8 @@ \section1 Print Handler - In the \c{PrintHandler} function, we first implement \c{printPreview()}, - where we instantiate \l{QPrinter} together with \l{QPrintPreviewDialog}. + In the \c{PrintHandler} class, we first implement \c{printPreview()}, + where we instantiate \l{QPrintPreviewDialog}. We need the \l{QPrintPreviewDialog::paintRequested} handle to generate a set of preview pages. @@ -77,16 +77,23 @@ Now we can implement the \c{PrintHandler::printDocument()} slot, which is called in response to the \l{QPrintPreviewDialog::paintRequested} signal. + To do actual painting on a printer, we call the \l QWebEngineView::print() + function. Because this call is asynchronous, we need to use + a local event loop. We begin the local event loop by calling + \l{QEventLoop::exec()}. \quotefromfile webenginewidgets/printme/printhandler.cpp \skipto PrintHandler::printDocument( \printuntil /^\}/ - To do actual painting on a printer, we call the \l QWebEngineView::print() - function. Because this call blocks the main event loop, we need to create - a local one. We begin the local event loop by calling - \l{QEventLoop::exec()}. When the local event loop terminates, - we check for \c{result} and report any errors that occurred. + To get notified about the result of printing job, we implement + \c{PrintHandler::printFinished()} slot as handler of + \l QWebEngineView::printFinished() signal. We check for \c{success} and + report any errors that occurred. + + \quotefromfile webenginewidgets/printme/printhandler.cpp + \skipto PrintHandler::printFinished( + \printuntil /^\}/ The last function we implement, \c{PrintHandler::print()}, is trivial, because it simply opens \l{QPrintDialog} and calls the previously diff --git a/examples/webenginewidgets/printme/printhandler.cpp b/examples/webenginewidgets/printme/printhandler.cpp index 200f2f302..283a6657c 100644 --- a/examples/webenginewidgets/printme/printhandler.cpp +++ b/examples/webenginewidgets/printme/printhandler.cpp @@ -49,9 +49,7 @@ ****************************************************************************/ #include "printhandler.h" -#include #include -#include #include #include #include @@ -59,7 +57,7 @@ PrintHandler::PrintHandler(QObject *parent) : QObject(parent) { - + m_printer.setResolution(300); } void PrintHandler::setView(QWebEngineView *view) @@ -67,36 +65,37 @@ void PrintHandler::setView(QWebEngineView *view) Q_ASSERT(!m_view); m_view = view; connect(view, &QWebEngineView::printRequested, this, &PrintHandler::printPreview); + connect(view, &QWebEngineView::printFinished, this, &PrintHandler::printFinished); } void PrintHandler::print() { - QPrinter printer(QPrinter::HighResolution); - QPrintDialog dialog(&printer, m_view); + QPrintDialog dialog(&m_printer, m_view); if (dialog.exec() != QDialog::Accepted) return; - printDocument(&printer); + printDocument(&m_printer); } void PrintHandler::printDocument(QPrinter *printer) { - QEventLoop loop; - bool result; - connect(m_view, &QWebEngineView::printFinished, [&](bool success) { result = success; loop.quit(); }); m_view->print(printer); - loop.exec(); - if (!result) { + m_waitForResult.exec(); +} + +void PrintHandler::printFinished(bool success) +{ + if (!success) { QPainter painter; - if (painter.begin(printer)) { + if (painter.begin(&m_printer)) { QFont font = painter.font(); font.setPixelSize(20); painter.setFont(font); painter.drawText(QPointF(10,25), QStringLiteral("Could not generate print preview.")); - painter.end(); } } + m_waitForResult.quit(); } void PrintHandler::printPreview() @@ -106,9 +105,7 @@ void PrintHandler::printPreview() if (m_inPrintPreview) return; m_inPrintPreview = true; - QPrinter printer; - printer.setResolution(300); - QPrintPreviewDialog preview(&printer, m_view); + QPrintPreviewDialog preview(&m_printer, m_view); connect(&preview, &QPrintPreviewDialog::paintRequested, this, &PrintHandler::printDocument); preview.exec(); diff --git a/examples/webenginewidgets/printme/printhandler.h b/examples/webenginewidgets/printme/printhandler.h index 663fd73d6..ca5d0b03b 100644 --- a/examples/webenginewidgets/printme/printhandler.h +++ b/examples/webenginewidgets/printme/printhandler.h @@ -51,7 +51,9 @@ #ifndef PRINTHANDLER_H #define PRINTHANDLER_H +#include #include +#include QT_BEGIN_NAMESPACE class QPainter; @@ -70,9 +72,12 @@ public slots: void print(); void printPreview(); void printDocument(QPrinter *printer); + void printFinished(bool success); private: QWebEngineView *m_view = nullptr; + QPrinter m_printer; + QEventLoop m_waitForResult; bool m_inPrintPreview = false; }; -- cgit v1.2.3