QT QWebEnginePage::setWebChannel() transport object

Short answer: add <script type="text/javascript" src="https://stackoverflow.com/questions/31928444/qrc:///qtwebchannel/qwebchannel.js"></script> to your html page (before you call new QWebChannel of course), and remove the line view->page()->runJavaScript(qwebjs); //this is qwebchannel.js from your C++ code.

Long answer:

I too had a ton of trouble figuring out how to use QWebChannel without WebSockets correctly — managed to get it working after digging around in Qt 5.5 source code and mailing lists (documentation is still lacking). Note that this only works with the new Qt 5.5.

Here’s how to use 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);

And on the JS side:

<!-- NOTE: this is what you're missing -->
<script type="text/javascript" src="https://stackoverflow.com/questions/31928444/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>

Also make sure you’ve added QT += webenginewidgets webchannel to your .pro file else this won’t build!

Bonus: you can debug your JavaScript from the comfort of Chrome Dev Tools now! Just add this somewhere in your Qt code (ideally in your application startup):

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

Then start your application, navigate to http://localhost:23654 in Chrome, and you’ll get a fully-functional JS debugger, profiler, console, etc 🙂


Follow-up (19/04/2016): if your remote debugger isn’t working, note that the qputenv call must also occur before any calls to QWebEngineSettings or any other WebEngine-related class, because these trigger the WebEngine “zygote” process immediately (the zygote is the parent QtWebEngineProcess from which all future QtWebEngineProcesses are forked) and then qputenv cannot affect it. Spent a few hours tracking this down.

Leave a Comment