QT QWebEnginePage:: транспортный объект setWebChannel()
Я использую Qt WebEngine framework для отображения веб-страниц. Я вставляю javascript в страницу, когда она загружается, и хочу, чтобы javascript мог получить доступ к объекту QT. По-видимому, для этого должен существовать QWebChannel, который устанавливает некоторый IPC между chromium (javascript) и остальной частью моего проекта C++/QT. Я наткнулся на функцию 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) и хотел бы избежать WebSockets, если это возможно.
ниже, как я пробовал реализовать веб-канал.
всякий раз, когда загружается страница, я устанавливаю канал и вставляю javascript в C++:
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). Любые указатели на примеры настройки QWebChannel с помощью QWebEnginePage также оцененный.
1 ответов
короткий ответ: добавить <script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
на html-страницу (перед вызовом new QWebChannel
конечно), и удалить строку view->page()->runJavaScript(qwebjs); //this is qwebchannel.js
в коде C++.
ответ:
у меня тоже была тонна проблем с тем, как правильно использовать QWebChannel без WebSockets-удалось заставить его работать после копания в исходном коде 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);
и на стороне 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
файл иначе это не будет строить!
бонус: теперь вы можете отлаживать JavaScript, не выходя из Chrome Dev Tools! Просто добавьте это где-нибудь в свой Qt-код (в идеале при запуске приложения):
#ifdef QT_DEBUG
qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "23654");
#endif
затем запустите приложение, выберите http://localhost:23654
в Chrome, и вы получите полнофункциональный отладчик JS, профилировщик, консоль и т. д.:)
продолжение (19/04/2016): если ваш удаленный отладчик не работает, обратите внимание, что qputenv
вызов также должен произойти до все вызовы QWebEngineSettings
или любой другой класс, связанный с WebEngine, потому что они немедленно запускают процесс WebEngine " zygote "(zygote-Родительский QtWebEngineProcess, из которого все будущие QtWebEngineProcesses раздвоены) а потом qputenv
не может повлиять на это. Потратил несколько часов на поиски.