QT QWebEnginePage::setWebChannel() 传输对象
QT QWebEnginePage::setWebChannel() transport object
我正在使用 QT WebEngine 框架来显示网页。我在页面加载时将 javascript 注入页面,并希望 javascript 能够访问 QT 对象。显然,要做到这一点,必须存在一个 QWebChannel,它在 Chromium(javascript)和我的 C++/QT 项目的其余部分之间建立一些 IPC。我遇到了 QWebEnginePage::setWebChannel (QWebChannel *channel) 函数,但是我找不到它的任何使用示例。文档 (http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel) mentions that qt.webChannelTransport should be available in the javascript context, but I don't see where that is established in qwebchannel.js (https://github.com/qtproject/qtwebchannel/blob/dev/src/webchannel/qwebchannel.js). I've seen the WebChannel examples (http://doc.qt.io/qt-5/qtwebchannel-examples.html) 并希望尽可能避免使用 WebSockets。
以下是我尝试实现网络频道的方式。
每当加载页面时,我都会建立一个通道并在 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 的示例的指针也很受欢迎。
简短回答: 将 <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
添加到您的 html 页面(当然是在调用 new QWebChannel
之前),然后删除行 view->page()->runJavaScript(qwebjs); //this is qwebchannel.js
来自你的 C++ 代码。
长答案:
我在弄清楚如何在没有 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
调用也必须发生 before 任何调用 QWebEngineSettings
或任何其他与 WebEngine 相关的 class,因为这些会立即触发 WebEngine "zygote" 进程(zygote 是父 QtWebEngineProcess,所有未来的 QtWebEngineProcesses 是分叉的)然后 qputenv
不能影响它。花了几个小时来追踪这个。
我正在使用 QT WebEngine 框架来显示网页。我在页面加载时将 javascript 注入页面,并希望 javascript 能够访问 QT 对象。显然,要做到这一点,必须存在一个 QWebChannel,它在 Chromium(javascript)和我的 C++/QT 项目的其余部分之间建立一些 IPC。我遇到了 QWebEnginePage::setWebChannel (QWebChannel *channel) 函数,但是我找不到它的任何使用示例。文档 (http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel) mentions that qt.webChannelTransport should be available in the javascript context, but I don't see where that is established in qwebchannel.js (https://github.com/qtproject/qtwebchannel/blob/dev/src/webchannel/qwebchannel.js). I've seen the WebChannel examples (http://doc.qt.io/qt-5/qtwebchannel-examples.html) 并希望尽可能避免使用 WebSockets。
以下是我尝试实现网络频道的方式。
每当加载页面时,我都会建立一个通道并在 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 的示例的指针也很受欢迎。
简短回答: 将 <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
添加到您的 html 页面(当然是在调用 new QWebChannel
之前),然后删除行 view->page()->runJavaScript(qwebjs); //this is qwebchannel.js
来自你的 C++ 代码。
长答案:
我在弄清楚如何在没有 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
调用也必须发生 before 任何调用 QWebEngineSettings
或任何其他与 WebEngine 相关的 class,因为这些会立即触发 WebEngine "zygote" 进程(zygote 是父 QtWebEngineProcess,所有未来的 QtWebEngineProcesses 是分叉的)然后 qputenv
不能影响它。花了几个小时来追踪这个。