QT QWebEnginePage :: setWebChannel () транспортный объект

Я использую инфраструктуру QT WebEngine для отображения веб-страниц. Я вставляю javascript в страницу, когда она загружается, и хочу, чтобы javascript мог иметь доступ к объекту QT. По-видимому, для этого должен существовать QWebChannel, который устанавливает IPC между хромом (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 также приветствуются.

8

Решение

Короткий ответ: добавлять <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 класс, потому что они немедленно запускают процесс «zygote» WebEngine (zygote является родительским QtWebEngineProcess, из которого разветвляются все будущие QtWebEngineProcesses), а затем qputenv не может повлиять на это. Потратил несколько часов, чтобы выследить это.

22

Другие решения


По вопросам рекламы [email protected]