Qt Qwebenginepage::Setwebchannel() Transport Object

QT QWebEnginePage::setWebChannel() transport object

Short answer: add <script type="text/javascript" src="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="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.

QWebEngine & QWebChannel: transport object `qt.webChannelTransport` disappeared after page reload

It is a bug, fix will be in Qt5.7.1, please see https://bugreports.qt.io/browse/QTBUG-53411 and http://code.qt.io/cgit/qt/qtwebengine.git/commit/?h=dev&id=ca6762abde85fe3104ec4f064b85319474ba2deb

QT QWebchannel not able to access CPP object methods or properties

JSHelper class misses Q_OBJECT macro. As the official documentation says,

Notice that the Q_OBJECT macro is mandatory for any object that
implements signals, slots or properties. You also need to run the Meta
Object Compiler on the source file. We strongly recommend the use of
this macro in all subclasses of QObject regardless of whether or not
they actually use signals, slots and properties, since failure to do
so may lead certain functions to exhibit strange behavior.

Also the constructor of this class needs to be made public for Qt's introspection facilities to be able to work with the class.

qt.webChannelTransport undefined in QWebEngineView

Thats correct.

QWebChannel integration with QWebEngine is only available from version 5.5 as stated here by Milian, the main developer of the module.

Undefined properties and return types when using QWebChannel

I had the same issue recently. After some investigation, I figured out how to make it work. Big thanks to the answer of this question: How to use Qt WebEngine and QWebChannel?

In order to get the return value of a method of your QObject, you need to define a Q_PROPERTY wrapping your QObject method. For example:

class SharedObject : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE int getIntValue();
Q_PROPERTY(int intValue READ getIntValue)

Q_INVOKABLE QString getStringValue();
Q_PROPERTY(QString stringValue READ getStringValue)
}

And then in your HTML, do this:

  <script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
new QWebChannel(qt.webChannelTransport, function (channel) {
window.sharedObject = channel.objects.sharedObject;
alert("intValue: " + sharedObject.intValue);
alert("stringValue: " + sharedObject.stringValue);
});
});
</script>

You should be able to see intValue and stringValue in your JavaScript code. The important bit is to use Q_PROPERTY I think.

Anyway, this resolves my problem, and I hope it helps for someone else too.



Related Topics



Leave a reply



Submit