WebEngine Widgets PrintMe Beispiel

Zeigt, wie man Webseiten mit Qt WebEngine Widgets druckt.

PrintMe demonstriert, wie die Klassen QWebEnginePage und QPrintDialog zum Drucken einer Webseite verwendet werden können. Außerdem wird gezeigt, wie die Druckvorschau mit Hilfe der Klasse QPrintPreviewDialog implementiert wird. Der Vollständigkeit halber wird auch gezeigt, wie eine Druckanforderung in JavaScript ausgelöst werden kann.

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorauszuführen, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Einfache HTML-Seite

In diesem Beispiel erstellen wir eine interne HTML-Seite, die als Ressourcensammlungsdatei (.qrc) hinzugefügt wird. Die Seite zeigt nur ein kleines HTML-Meldungsfeld an, in dem erklärt wird, wie der Druckvorgang über Tastenkombinationen oder durch Klicken auf eine Schaltfläche ausgelöst werden kann. Die Schaltfläche hat das JavaScript-Ereignisattribut onclick, das die JavaScript-Funktion window.print() aufruft.

<html lang="en">
   <head>
      <meta charset="utf-8">
      <title>PrintMe</title>
      <link rel="stylesheet" type="text/css" href="style.css">
      <script>
      function printNow() {
         window.print();
      }
      </script>
   </head>
   <body>
      <form class="form">
         <div class="header">
            <h1>Hello Paper World!</h1>
            <h2>Press Ctrl+p to print with print preview</h2>
            <h2>Press Ctrl+Shift+p to print without print preview</h2>
            <h2>Click the button to print using JavaScript</h2>
            <p class="button" onclick="printNow()">Print Now</p>
         </div>
      </form>
   </body>
</html>

Hauptfunktion

In der Funktion main instanziieren wir zunächst eine QWebEngineView und setzen die URL auf unsere interne HTML-Seite. Als nächstes erstellen wir eine PrintHandler Instanz und übergeben die angeforderte Seite. Der Einfachheit halber erstellen wir auch Tastaturkürzel, die zum Aufrufen eines Druckdialogs oder eines Druckvorschau-Dialogs verwendet werden können.

    QWebEngineView view;
    view.setUrl(QUrl(QStringLiteral("qrc:/index.html")));
    view.resize(1024, 750);
    view.show();

    PrintHandler handler;
    handler.setView(&view);

    auto printPreviewShortCut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_P), &view);
    auto printShortCut = new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_P), &view);

    QObject::connect(printPreviewShortCut, &QShortcut::activated, &handler, &PrintHandler::printPreview);
    QObject::connect(printShortCut, &QShortcut::activated, &handler, &PrintHandler::print);

In der Klasse PrintHandler implementieren wir zunächst printPreview(), wobei wir QPrintPreviewDialog instanziieren. Wir benötigen das QPrintPreviewDialog::paintRequested -Handle, um eine Reihe von Vorschauseiten zu erzeugen.

void PrintHandler::printPreview()
{
    if (!m_view)
        return;
    if (m_inPrintPreview)
        return;
    m_inPrintPreview = true;
    QPrintPreviewDialog preview(&m_printer, m_view);
    connect(&preview, &QPrintPreviewDialog::paintRequested,
            this, &PrintHandler::printDocument);
    preview.exec();
    m_inPrintPreview = false;
}

Nun können wir den Slot PrintHandler::printDocument() implementieren, der als Reaktion auf das Signal QPrintPreviewDialog::paintRequested aufgerufen wird. Um tatsächlich auf einem Drucker zu malen, rufen wir die Funktion QWebEngineView::print() auf. Drucken ist eine asynchrone Operation in Chromium, aber nicht in Qt, also führen wir eine lokale Ereignisschleife mit QEventLoop::exec() aus, um sicherzustellen, dass das Drucken vor der Rückkehr abgeschlossen ist. Benutzereingaben werden blockiert, da das Klicken auf eine Schaltfläche, während wir auf den Abschluss des Druckvorgangs warten, den internen Status durcheinander bringen und einen Absturz verursachen kann.

void PrintHandler::printDocument(QPrinter *printer)
{
    m_view->print(printer);
    // User input in the print preview dialog while we're waiting on a print task
    // can mess up the internal state and cause a crash.
    m_waitForResult.exec(QEventLoop::ExcludeUserInputEvents);
}

Um über das Ergebnis des Druckauftrags informiert zu werden, implementieren wir den Slot PrintHandler::printFinished() als Handler des Signals QWebEngineView::printFinished(). Wir prüfen auf success und melden alle aufgetretenen Fehler. Schließlich rufen wir QEventLoop::quit() auf, um die lokale Ereignisschleife zu verlassen.

void PrintHandler::printFinished(bool success)
{
    if (!success) {
        QPainter painter;
        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();
}

Die letzte Funktion, die wir implementieren, PrintHandler::print(), ist trivial, da sie einfach QPrintDialog öffnet und die zuvor implementierte PrintHandler::printDocument() aufruft.

void PrintHandler::print()
{
    QPrintDialog dialog(&m_printer, m_view);
    if (dialog.exec() != QDialog::Accepted)
        return;
    printDocument(&m_printer);
}

Beispielprojekt @ code.qt.io

© 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.