我正在尝试从我的应用程序中打印一份报告,其中涉及文本和表格。由于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。所以我想以上只是偶然的。
方法二:直接打印
这种方法崩溃:
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
吗?