mat*_*fis 12 c++ qt qtwebengine qt5.5
I'm using the QT WebEngine framework to display web pages. I'm injecting javascript into a page when it loads, and want to allow the javascript to be able to access a QT object. Apparently, to do this a QWebChannel must exist that establishes some IPC between chromium (the javascript) and the rest of my C++/QT project. I came across the QWebEnginePage::setWebChannel (QWebChannel*channel) function, however I can't find any examples of its use. The documentation (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)
Run Code Online (Sandbox Code Playgroud)
在Javascript中:
new QWebChannel(qt.webChannelTransport, function(channel) { ... });
Run Code Online (Sandbox Code Playgroud)
这导致通道未正确连接(假设这是因为qt.webChannelTransport,因为它在我使用WebSockets时工作).任何使用QWebEnginePage以这种方式设置的QWebChannel示例的指针也是值得赞赏的.
Vic*_*ani 27
简短的回答:添加<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源代码和邮件列表(文档仍然缺乏)之后设法使其工作.请注意,这仅适用于新的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);
Run Code Online (Sandbox Code Playgroud)
在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>
Run Code Online (Sandbox Code Playgroud)
还要确保你已经添加QT += webenginewidgets webchannel到你的.pro文件中,否则这将无法构建!
额外奖励:您现在可以在Chrome Dev Tools中轻松调试JavaScript!只需在Qt代码中添加它(理想情况下在应用程序启动时):
#ifdef QT_DEBUG
qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "23654");
#endif
Run Code Online (Sandbox Code Playgroud)
然后启动您的应用程序,导航到http://localhost:23654Chrome,您将获得一个功能齐全的JS调试器,分析器,控制台等:)
后续(2016年4月19日):如果您的远程调试器不工作,请注意在任何调用或任何其他与WebEngine相关的类之前qputenv也必须进行调用QWebEngineSettings,因为它们会立即触发WebEngine"zygote"进程( zygote是父QtWebEngineProcess,所有未来的QtWebEngineProces都是分叉的,然后qputenv不能影响它.花了几个小时追踪这个.