4

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.]

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • have you checked c++ `QJSEngine` – Mohammad Kanan May 16 '18 at 16:30
  • You can try to include the "qwebchanne.js" file directly as shown in the QWebChannel examples. – Felix May 16 '18 at 22:25
  • @Felix, `qwebchannel.js` works as mentioned in the 2nd part of the Qn. But, it uses JSON. We want to avoid JSON due to its over descriptive nature. Because lots of text will be passed over internet, if the GUI/JavaScript & client/C++ are separated by wire. Were you suggesting something else? – iammilind May 17 '18 at 02:00

1 Answers1

3

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.

Guru_07
  • 362
  • 3
  • 15
  • Yes as mentioned in the Qn. The default way is to use Qt provided custom JSON way. Since lots of function calling is involved, json is expensive over internet. We want to find another Qt way or trick to determine better alternatives except JSON. Still I upvoted for efforts. :-) – iammilind May 17 '18 at 03:43
  • @iammilind: The above answer provides an alternate way; Transmission over the wire will not be json but the Protobuf /custom protocol, as may be needed – Guru_07 May 17 '18 at 04:13