For desktops (Windows, Mac, Ubuntu), there is a QWebEngineView
and for mobiles (Android, iOS), there is a native QWebView
.
Unfortunately, mobiles don't support QWebEngineView
.
For example, as discussed in below post:
How to use Qt WebEngine and QWebChannel?
The setWebChannel()
is available in QWebEnginePage
which is accessible only in QWebEngineView
. However, QWebPage
doesn't have such method which is accessible in QWebView
.
Now, there is another platform independent way, which works on all the platforms, as discussed in Integrating Web Content.
But the example uses QWebChannelAbstractTransport
, which can be used only with JSON
. Now JSON, due to its over-descriptive nature, could be quite expensive, if the C++ module is sitting somewhere in server and HTML is local; i.e. real client-server communication over internet.
It would have been better, had they use protobuf.
Is there any optimised and platform agnostic way of calling HTML/Javascript from C++ in Qt?
[Note: BTW, current Qt way of calling C++ from Javascript is quite handy using channel.objects
and I would like to retain that way.]
With QWebChannel to communicate between C++ and HTML/JS, Qt currently, uses JSON to transport event invocation/data (see QWebChannelAbstractTransport & QWebChannel.js). Over the internet, JSON when compared to Google Protobuf, may be having a overhead of sending field names but this should be negligible compared to 'No data (strings/text) optimization" in either protocols.
Is there any optimised and platform agnostic way of calling HTML/Javascript from C++ in Qt?
The optimized way would be for Qt to provide string/bytes (instead of QJsonObject) in QWebChannelAbstractTransport and JS (both the connection ends) so that we can use custom protocols for transport.
A work around/alternate solution (may not be the optimized way) would be to use the current abstraction to transport using Protobuf/custom protocol like here:
Refer to Qt WebChannel Examples
In websockettransport.cpp (shared folder in examples)
C++
void WebSocketTransport::sendMessage(const QJsonObject &message)
// Convert message from QJsonObject to Protobuf/custom protocol and
// use m_socket->sendTextMessage or sendBinaryMessage as required
void WebSocketTransport::textMessageReceived(const QString &messageData)
//with QWebSocket::binary[ or text]MessageReceived slot,
//convert the message from client (in Protobuf/custom protocol) to
//JSON and still
emit messageReceived(message.object(), this);
JS: Similarly, since the QWebChannel.js uses socket, need to set the socket to binary or text as required and convert the ProtoBuf/custom protocol message to json as needed by Qt
Simple illustration on using Protobuf (needs all messages to be predefined)/custom protocol in QWebchannel:
C++ -> WebSocketTransport (JSON to Protobuf/custom protocol) -> transmit -> websocket JS (Protobuf/custom protocol to JSON) -> (QWebChannel.js)
JS -> (QWebChannel.js) -> websocket JS (JSON to Protobuf/custom protocol) -> transmit -> WebSocketTransport (Protobuf/custom protocol to JSON) -> C++
Note: JS works on objects (from JSON or any protocol) and may not need conversion as said above; but this needs to be determined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With