简体   繁体   English

QtWebEngine:打印由javascript调用的网页

[英]QtWebEngine: Printing a webpage invoked by javascript

From here , I know that I can use QWebEngineView::render , passing in a pointer to my QPrinter object to programmatically print a web page. 这里开始 ,我知道我可以使用QWebEngineView::render ,传入指向我的QPrinter对象的指针以编程方式打印网页。

But if the print request was invoked by javascript (from the window.print() javascript function for instance), I don't know how to catch that request to then hand off to my print function. 但是,如果打印请求是由javascript调用的(例如,从window.print() javascript函数),则我不知道如何捕获该请求然后转交给我的打印功能。

Two years later I finally came up with a solution to this problem. 两年后,我终于想出了解决这个问题的方法。

Qt 5.8 does support printing, however chooses to completely ignore javascript invoked window.print() requests. Qt 5.8 确实支持打印,但是选择完全忽略javascript调用的window.print()请求。

The solution is to inject some javascript to override the window.print() function: 解决方案是注入一些JavaScript来覆盖window.print()函数:

class JavascriptInvokedPrintComm : public QWebChannel
{
    Q_OBJECT
public:
    JavascriptInvokedPrintComm(QObject *parent) : QWebChannel(parent)
    {
        registerObject("webEngineViewBridge", this);
    }

public slots:
    void print()
    {
        emit printRequest();
    }

signals:
    void printRequest();
};

class MyWebEngineView : public QWebEngineView
{
    Q_OBJECT
public:
    MyWebEngineView(QWdidget *parent) :  QWebEngineView(parent)
    {
        // Inject qwebchannel.js so that we can handle javascript invoked printing
        QWebEngineScript webChannelJs;
        webChannelJs.setInjectionPoint(QWebEngineScript::DocumentCreation);
        webChannelJs.setWorldId(QWebEngineScript::MainWorld);
        webChannelJs.setName("qwebchannel.js");
        webChannelJs.setRunsOnSubFrames(true);
        {
            QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
            webChannelJsFile.open(QFile::ReadOnly);
            webChannelJs.setSourceCode(webChannelJsFile.readAll());
        }
        page()->scripts().insert(webChannelJs);

        // Inject some javascript to override the window.print() function so that we can actually catch and handle
        // javascript invoked print requests
        QWebEngineScript overrideJsPrint;
        overrideJsPrint.setInjectionPoint(QWebEngineScript::DocumentCreation);
        overrideJsPrint.setWorldId(QWebEngineScript::MainWorld);
        overrideJsPrint.setName("overridejsprint.js");
        overrideJsPrint.setRunsOnSubFrames(true);
        overrideJsPrint.setSourceCode(
                    "window.print = function() { "
                    "   new QWebChannel(qt.webChannelTransport, function(channel) { "
                    "       var webEngineViewBridge = channel.objects.webEngineViewBridge; "
                    "       webEngineViewBridge.print(); "
                    "   });"
                    "};"
                    );
        page()->scripts().insert(overrideJsPrint);

        JavascriptInvokedPrintComm *jsInvokedPrintComm = new JavascriptInvokedPrintComm(this);
        connect(jsInvokedPrintComm, &JavascriptInvokedPrintComm::printRequest, [this]()
        {
            QPrintDialog *prntDlg = new QPrintDialog(this);
            if(!prntDlg->exec())
            {
                prntDlg->deleteLater();
                return;
            }

            page()->print(prntDlg->printer(),
                [prntDlg](bool ok)
                {
                    Q_UNUSED(ok);
                    prntDlg->deleteLater();
                }
            );
        });
    }
}

*Not compile tested, but conceptual this should work *未经编译测试,但从概念上讲应该可行

Which version of Qt do you use? 您使用哪个版本的Qt? Currently printing is not supported under version 5.6. 当前在5.6版下不支持打印。

See the plan: https://trello.com/c/JE5kosmC/72-printing-support 查看计划: https : //trello.com/c/JE5kosmC/72-printing-support

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM