【问题标题】:QT QWebEnginePage::setWebChannel() transport objectQT QWebEnginePage::setWebChannel() 传输对象
【发布时间】:2015-11-02 21:24:32
【问题描述】:

我正在使用 QT WebEngine 框架来显示网页。我在加载页面时将 javascript 注入到页面中,并希望允许 javascript 能够访问 QT 对象。显然,要做到这一点,必须存在一个在铬(javascript)和我的 C++/QT 项目的其余部分之间建立一些 IPC 的 QWebChannel。我遇到了 QWebEnginePage::setWebChannel (QWebChannel *channel) 函数,但是我找不到任何使用它的例子。文档 (http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel) 提到 qt.webChannelTransport 应该在 javascript 上下文中可用,但我看不到在 qwebchannel.js (https://github.com/qtproject/qtwebchannel/blob/dev/src/webchannel/qwebchannel.js) 中建立的位置。我已经看过 WebChannel 示例 (http://doc.qt.io/qt-5/qtwebchannel-examples.html),并希望尽可能避免使用 WebSocket。

以下是我尝试实现网络频道的方法。

每当页面加载时,我都会建立一个通道并在 C++ 中注入 javascript:

QWebChannel *channel = new QWebChannel();
channel->registerObject(QStringLiteral("jshelper"), helper);

view->page()->runJavaScript(qwebjs); //this is qwebchannel.js
view->page()->setWebChannel(channel);
view->page()->runJavaScript(myfunction); //function that calls QT object (jshelper)

在 Javascript 中:

new QWebChannel(qt.webChannelTransport, function(channel) { ... });

这会导致通道未正确连接(假设这是因为 qt.webChannelTransport,因为它在我使用 WebSockets 时正在工作)。任何指向以这种方式使用 QWebEnginePage 设置的 QWebChannel 示例的指针也值得赞赏。

【问题讨论】:

    标签: c++ qt qtwebengine qt5.5


    【解决方案1】:

    简答:<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script> 添加到您的html 页面(当然是在您调用new QWebChannel 之前),并从您的C++ 代码中删除view->page()->runJavaScript(qwebjs); //this is qwebchannel.js 行。

    长答案:

    我在弄清楚如何在没有 WebSockets 的情况下正确使用 QWebChannel 方面也遇到了很多麻烦——在研究 Qt 5.5 源代码和邮件列表(仍然缺乏文档)之后设法让它工作。请注意,这只适用于the new Qt 5.5

    QWebChannel的使用方法如下:

    // file: MyWebEngineView.cpp, MyWebEngineView extends QWebEngineView
    QWebChannel *channel = new QWebChannel(page());
    
    // set the web channel to be used by the page
    // see http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel
    page()->setWebChannel(channel);
    
    // register QObjects to be exposed to JavaScript
    channel->registerObject(QStringLiteral("jshelper"), helper);
    
    // now you can call page()->runJavaScript(...) etc
    // you DON'T need to call runJavaScript with qwebchannel.js, see the html file below
    
    // load your page
    load(url);
    

    在 JS 方面:

    <!-- NOTE: this is what you're missing -->
    <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
    
    <script type="text/javascript">
        <!-- it's a good idea to initialize webchannel after DOM ready, if your code is going to manipulate the DOM -->
        document.addEventListener("DOMContentLoaded", function () {
            new QWebChannel(qt.webChannelTransport, function (channel) {
                var jshelper = channel.objects.jshelper;
                // do what you gotta do
            });
        });
    </script>
    

    还要确保您已将 QT += webenginewidgets webchannel 添加到您的 .pro 文件中,否则将无法构建!

    奖励:您现在可以在舒适的 Chrome 开发工具中调试您的 JavaScript!只需在您的 Qt 代码中的某处添加它(最好是在您的应用程序启动中):

    #ifdef QT_DEBUG
        qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "23654");
    #endif
    

    然后启动您的应用程序,在 Chrome 中导航到 http://localhost:23654,您将获得一个功能齐全的 JS 调试器、分析器、控制台等 :)


    跟进 (19/04/2016):如果您的远程调试器不工作,请注意qputenv 调用也必须发生在任何调用之前到QWebEngineSettings 或任何其他与WebEngine 相关的类,因为它们会立即触发WebEngine“zygote”进程(zygote 是所有未来QtWebEngineProcesses 的父QtWebEngineProcess),然后qputenv 不能影响它。花了几个小时追查此事。

    【讨论】:

    • 这很棒——我唯一的问题是我必须注入脚本,因为我无法控制正在加载的页面。另外,当您说“新的 QT 5.5”时,您的意思是来自 dev 分支吗?我正在使用 QT Creator 5.5.0,但我不确定我正在使用的 QT 源代码是如何更新的。我尝试使用环境变量设置在控制台中调试 JS,但它不起作用(我认为是因为此调试选项来自最近的提交)。
    • 我明白了。在 Qt Creator 中,转到 Tools > Options > Build & Run > Qt Versions 并检查您拥有的版本。当我说 Qt 5.5 时,我的意思是 the stable version that was released on July 1st of this year。 Qt 5.5 在 QWebChannel 上添加了对 Chromium IPC 的内置支持(即 JS 中的 QWebEnginePage::setWebChannel()qt.webChannelTransport)。另外,你的 Qt Creator 不能是 v5.5,the latest version is v3.4.2 :)
    • 另外,QTWEBENGINE_REMOTE_DEBUGGING 出现在 Qt 5.5 版本中:stackoverflow.com/a/29721197/504611
    • 注意:在析构函数中如果助手有父 dergister 助手; page()->webChannel()->deregisterObject(helper);
    • @OlehPomazan 是的,我也经历过同样的事情:网络频道在页面重新加载时效果不佳。也许他们会在以后的版本中解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多