Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup QWebChannel JS API for use in a QWebEngineView?

Tags:

c++

javascript

qt

As Qt's documentation is far from complete, which are the ways to setup QWebChannel and are there different ones from adding a <script> tag in your HTML page like recommended in the documentation?

like image 227
ThunderStorm Avatar asked Sep 22 '16 22:09

ThunderStorm


1 Answers

There are different options to load the needed script accessible at the URL qrc:///qtwebchannel/qwebchannel.js:

Notice:

  • you can only use that URL if you are viewing the page from within QWebEngineView. Otherwise you might need to load the API file to your webserver.

Prerequisites:

  • add QT += webchannel to your .pro file and run qmake

Using runJavaScript() to execute the code in Qt's QWebChannel JS API:

My prefered method because it seems simple and has been reliable so far. Keep in mind the possibility that the API might not be set up by the time this code has finished as the runJavaScript() method does not block the current thread until the JS code has been executed.

QFile apiFile(":/qtwebchannel/qwebchannel.js"); //load the API from the resources
if(!apiFile.open(QIODevice::ReadOnly))
    qDebug()<<"Couldn't load Qt's QWebChannel API!";
QString apiScript = QString::fromLatin1(apiFile.readAll());
apiFile.close();
QWebEngineView view;    //your custom QWebEngineView
view.page().runJavaScript(apiScript);

Using runJavaScript() to execute code to load Qt's QWebChannel JS API:

Although I didn't try these methods they should still work, as they aim to load external JS files. One of the methods suggested here might come in handy depending on which other libraries you use.

Using a <script> tag in the web page:

This is the default method recommended by Qt's documentation. It has the advantage of providing the API immediatly after the page was loaded. The downside of this is that you need to modify the HTML of the web page which can be painful if you are not the owner of the site.

Don't forget create a QWebChannel object on the C++ side:

QWebChannel* channel_ = new QWebChannel(view.page());
//attach it to the QWebEnginePage
view.page()->setWebChannel(channel_);
//register a QObject to be exposed to JavaScript
channel_->registerObject(QStringLiteral("jshelper"), this);

Set up the QWebChannel on the JavaScript code:

As pointed out in the comments in order to share objects between C++ and JavaScript you need to initialize the QWebChannel.

new QWebChannel(qt.webChannelTransport, function (channel) {
    var sharedObject = channel.objects.sharedObject;
});

This answer was thought as an addition to Qt's documentation, so if you want to add something feel free to do so.

Version: Qt 5.6.1

Sources:

  • QT QWebEnginePage::setWebChannel() transport object
  • How do I include a JavaScript file in another JavaScript file?
  • How to use Qt WebEngine and QWebChannel?
  • http://doc.qt.io/qt-5/qtwebchannel-javascript.html
like image 149
ThunderStorm Avatar answered Oct 24 '22 02:10

ThunderStorm