Introduction
The QT WebEngineView is the new method of providing applications that display, and interact with web pages.There is some documentation on the QT website on how to implement these functions, with references to the previous QWebView method, but these are lacking examples.
I have produced the following with QT5.5:
Download C++ QT Source for an example, which is a simple QT application with a dialog containing a widget (called HtmlPage). This widget is based on QWebEngineView, and extends it very slightly to:
- Initialise the web page, and set up a communications channel to it
- Provide a function to request the JavaScript web page to insert a dot at a given X/Y coordinate.
- Provide a function to receive information regarding a cursor movement and emit a signal to the main window.
- Initialise and set up a communications channel to the QT application
- Produce a dot at a given X/Y coordinate.
- Emit a signal (function call) to the QT application indicating the cursor has moved.
- Include a signal handler to place a large dot at the mouse cursor position, and emit a signal when the mouse is clicked.
- When the mouse is clicked (Javascript), the handler places a large dot at the cursor position.
- The Javascript then informs the QT C++ application with a £widget.functioncall£.
- Some time later (asynchronously), the C++ application receives the message in the "functioncall" slot.
- The C++ class emits a signal to the mainwindow to allow the X/Y coordinates to be updated on the screen.
- The C++ class then makes a call back to the Javascript to place a smaller dot at the same position.
- Some time later (asynchronously), the Javascript handler receives the message and places the dot.
C++
Add the "QT += webenginewidgets webchannel" to your project.pro file, and include the appropriate header files, and then in your C++ class / you need to set up the communications channel. Note that 'channel' should be declared in the class header.// Set up the communications channel for this QWebEngineView parented classTo call the Javascript, build a javascript function call into a string, and then call the page()->runJavascript() function.
this->page()->setWebChannel(&channel) ;
channel.registerObject("widget", this) ;
QString command = QString("javascriptFunction(%1);").arg(functionParameter) ;
page()->runJavaScript(command) ;
To receive messages from Javascript, public slots must be used:
public slots:
void updateComplete(int x) ;
Javascript
To initialise, the following script line should be included:<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>Then the <body> tag should have an onload="initialise()" option.
In the initialise function, the other end of the communications link should be set up, noting that the setting of (in this case) widget is asynchronous to the initialise function call. Note also that 'widget' should be a global variable.
var widget ;Some time after the initialisation, the widget variable will be defined (it will be of type QObject). You can emit signals to C++ simply by calling the appropriate function, so for example:
function initialise() {
if (typeof qt != 'undefined') new QWebChannel(qt.webChannelTransport, function(channel) {
widget = channel.objects.widget;
} );
}
widget.updateComplete(x) ;Will emit a signal which will be captured some time later in the updateComplete(int x) slot in the C++ class. You need to appreciate that all calls between C++ and Javascript are asynchronous with QtWebEngineView.
Very excellent article which helped me transition, very easily, from my experience with WebKit to the new WebEngine.
ReplyDeleteThank you so much for a great tutorial.
aouhlal
Good stuff. Helped me in my project.
ReplyDelete