Important: Please read the Qt Code of Conduct -

QWebChannel: how to register custom QObject types

  • Hi all,
    I'm using the example webchannel/standalone of Qt 5.9.4, I modified the "core" QObject that is registered on the QWebChannel to add a property that returns an object:
    Q_PROPERTY(MyObject * currentObject READ currentObject NOTIFY currentObjectChanged)

    MyObject is a custom QObject with properties and slots. One of the property is a QString "title". It is registered with Q_DECLARE_METATYPE(MyObject*), and also with qRegisterMetaType<MyObject*>("MyObject*");

    In my index.html, I have a script that uses core.currentObject.title. It is used in a REACT component like that:
    class MyObjectextends React.Component {
    render() {
    return (
    <div>{'Object: '} {core.currentObject ? core.currentObject.title: 'No Object'} </div>

    I'm re-rendering this component when I receive the currentObjectChanged signal. So when I first start the page I see 'No Object' and as soon as I receive the currentObjectChanged my page is updated: but instead of seeing the title I see nothing.
    In the Chrome 'Inspect' console I don't have errors. In the watch I can see core.currentObject, however I don't see its properties/slots, like I do for the core object.

    How do I register the prototype for my custom QObject to the scripting?

    I cannot call channel->registerObject(QStringLiteral("myobject"), myobject); because when I set-up the channel the instance of the object is not yet available.
    I know how to register a custom QObject* type to QScriptEngine, but I don't see how to do the equivalent on the QWebChannel.
    I looked into QMetaObjectPublisher but I'm getting nowhere.

    Any help is appreciated


  • Should I define the prototype of this custom object in a .js file, and set the prototype on the object when I receive it? I will investigate in this direction.

  • Ok, I was making it more complex than it is...
    I cannot call core.currentObject.title in my script BUT I still have access to its properties and slots. Everything was in the Inspect/Sources/Watch of Chrome and I just had to expand the "data" element of my object to see it!!

    So to get the title I have to write[2][3]

    Note that if I refresh the page then I see my currentObject as a QObject in the Chrome Watch, because the pointer is non-null when Qt wraps my core object to the scripting, and I can access core.currentObject.title. I need to figure out how to get it without doing a F5 on the page.

  • I fixed my problem by editing qwebchannel.js to wrap updated properties to QObjects

    this.propertyUpdate = function(signals, propertyMap)
    // update property cache
    for (var propertyIndex in propertyMap) {
    var propertyValue = propertyMap[propertyIndex];
    object.propertyCache[propertyIndex] = this.unwrapQObject(propertyValue); //changed to call unwrapQObject

    after that my property core.currentObject shows up as a QObject type

Log in to reply