1

テキストと表の両方を含むアプリケーション内からレポートを印刷しようとしています。QTextDocumentこれでは不十分なのでQWebEngineView、Qt リッチ テキスト エンジンでサポートされていない、より洗練された HTML/CSS を使用することにしました。

ビューから PDF を作成することはできますが、PDF 作成の代わりにクラッシュしたり、印刷がクラッシュしたりすることがあるため、一般的な誤解がいくつかあります。

これが私の試みです:


アプローチ 1: PDF の作成

これは唯一の機能するバリアントです。

    auto webView = new QWebEngineView();
    webView->setHtml(contents);

    const QString fn = QFileDialog::getSaveFileName(0, "Save pdf", ".", "PDF Files (*.pdf)");

    if (!fn.isEmpty())
       webView->page()->printToPdf(fn);

ただし、これはダイアログ (?!) が原因でのみ機能します。次のように変更すると:

    QString fn ="/Users/s710/Downloads/test.pdf";
    auto webView = new QWebEngineView();
    webView->setHtml(contents);
    webView->page()->printToPdf(fn);

空白ページを含む PDF を作成します。したがって、上記は偶然にしか機能しないと思います。


アプローチ 2: 直接印刷する

このアプローチはクラッシュします:

    auto webView = new QWebEngineView();
    webView->setHtml(contents);

    QPrinter printer(QPrinter::QPrinter::ScreenResolution);
    printer.setOutputFormat(QPrinter::NativeFormat);
    printer.setPaperSize(QPrinter::A4);
    printer.setPageMargins(12, 16, 12, 20, QPrinter::Millimeter);

    webView->page()->print(&printer, [](bool){});

Crash:
1   QPrinter::pageRect() const                                                                                                                                                                                                                                 (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport                       0x100247fe4    
2   QWebEnginePagePrivate::didPrintPage(unsigned long long, QByteArray const&)                                                                                                                                                                                 (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineWidgets.framework/Versions/5/QtWebEngineWidgets               0x100200f0a    
3   QtWebEngineCore::callbackOnPrintingFinished(QtWebEngineCore::WebContentsAdapterClient *, int, std::vector<char> const&)                                                                                                                                    (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineCore.framework/Versions/5/QtWebEngineCore                     0x100899693    
4   base::debug::TaskAnnotator::RunTask(const char *, base::PendingTask *)                                                                                                                                                                                     (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineCore.framework/Versions/5/QtWebEngineCore                     0x10295d402    
5   base::MessageLoop::RunTask(base::PendingTask *)                                                                                                                                                                                                            (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineCore.framework/Versions/5/QtWebEngineCore                     0x10298395f    
6   base::MessageLoop::DoWork()                                                                                                                                                                                                                                (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineCore.framework/Versions/5/QtWebEngineCore                     0x102983ef9    
7   std::__function::__func<QtWebEngineCore::(anonymous namespace)::MessagePumpForUIQt::MessagePumpForUIQt()::'lambda'(), std::allocator<QtWebEngineCore::(anonymous namespace)::MessagePumpForUIQt::MessagePumpForUIQt()::'lambda'()>, void ()>::operator()() (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineCore.framework/Versions/5/QtWebEngineCore                     0x100839f99    
8   QObject::event(QEvent *)                                                                                                                                                                                                                                   (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtCore.framework/Versions/5/QtCore                                       0x10824bcf6    
...

アプローチ 3: webview が読み込まれるのを待ってから PDF を作成する

そのため、ブロッキング ファイル ダイアログとの違いがあるように見えるので、ビューがまだ HTML を読み込んでいない場合に問題があるのではないかと考えました。また、リソースが重いことも読んだQWebEngineViewので、ロードが完了するまで待つことができると思いました.

ただし、これもクラッシュします

    auto webView = new QWebEngineView();

    QObject::connect(webView, &QWebEngineView::loadFinished, this, [&webView](bool ok)
    {
        QString fn ="/Users/s710/Downloads/test.pdf";
        webView->page()->printToPdf(fn);
    });

    webView->setHtml(contents);

Crash:
1   QWebEnginePage::printToPdf(QString const&, QPageLayout const&)                                                                                                                                                          (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineWidgets.framework/Versions/5/QtWebEngineWidgets     0x100204cd7    
2   Printer::print(MonthItem *, QWidget *)::$_0::operator()(bool) const                                                                                                                                                     printer.cpp                                                                                            203 0x100016eeb    
3   QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<bool>, void, Printer::print(MonthItem *, QWidget *)::$_0>::call(Printer::print(MonthItem *, QWidget *)::$_0&, void * *)                               qobjectdefs_impl.h                                                                                     146 0x100016dc8    
4   void QtPrivate::Functor<Printer::print(MonthItem *, QWidget *)::$_0, 1>::call<QtPrivate::List<bool>, void>(Printer::print(MonthItem *, QWidget *)::$_0&, void *, void * *)                                              qobjectdefs_impl.h                                                                                     256 0x100016d71    
5   QtPrivate::QFunctorSlotObject<Printer::print(MonthItem *, QWidget *)::$_0, 1, QtPrivate::List<bool>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *)                                        qobjectdefs_impl.h                                                                                     439 0x100016d1d    
6   QMetaObject::activate(QObject *, int, int, void * *)                                                                                                                                                                    (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtCore.framework/Versions/5/QtCore                             0x10825153b    
7   QWebEngineView::loadFinished(bool)                                                                                                                                                                                      (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineWidgets.framework/Versions/5/QtWebEngineWidgets     0x10020cb3f

アプローチ 4: webview が読み込まれるのを待ってから印刷する

これもクラッシュします:

    auto webView = new QWebEngineView();

    QObject::connect(webView, &QWebEngineView::loadFinished, this, [&webView](bool ok)
    {
        QPrinter printer(QPrinter::PrinterResolution);
        printer.setOutputFormat(QPrinter::NativeFormat);
        printer.setPaperSize(QPrinter::A4);
        printer.setPageMargins(12, 16, 12, 20, QPrinter::Millimeter);

        webView->page()->print(&printer, [](bool){});
    });

    webView->setHtml(contents);

Crash:
1   QWebEngineView::page() const                                                                                                                                                                                            (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineWidgets.framework/Versions/5/QtWebEngineWidgets     0x10020f05d    
2   Printer::print(MonthItem *, QWidget *)::$_0::operator()(bool) const                                                                                                                                                     printer.cpp                                                                                            207 0x100016b35    
3   QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<bool>, void, Printer::print(MonthItem *, QWidget *)::$_0>::call(Printer::print(MonthItem *, QWidget *)::$_0&, void * *)                               qobjectdefs_impl.h                                                                                     146 0x100016a88    
4   void QtPrivate::Functor<Printer::print(MonthItem *, QWidget *)::$_0, 1>::call<QtPrivate::List<bool>, void>(Printer::print(MonthItem *, QWidget *)::$_0&, void *, void * *)                                              qobjectdefs_impl.h                                                                                     256 0x100016a31    
5   QtPrivate::QFunctorSlotObject<Printer::print(MonthItem *, QWidget *)::$_0, 1, QtPrivate::List<bool>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void * *, bool *)                                        qobjectdefs_impl.h                                                                                     439 0x1000169dd    
6   QMetaObject::activate(QObject *, int, int, void * *)                                                                                                                                                                    (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtCore.framework/Versions/5/QtCore                             0x10825353b    
7   QWebEngineView::loadFinished(bool)                                                                                                                                                                                      (x86_64) /Users/s710/Qt/5.12.6/clang_64/lib/QtWebEngineWidgets.framework/Versions/5/QtWebEngineWidgets     0x10020eb3f    

いたるところでクラッシュしているので、私はかなりばかげているように感じますが、何が悪いのかわかりません。誰かがプリーズを使用して動作する印刷機能を教えてもらえますQWebEngineViewか?

4

1 に答える 1