Guillaume Depardon
Guillaume Depardon

Reputation: 174

QML callback from C++ with custom type as parameter

I would like to be able to call a QML function from C++ with an instance of a custom class as a parameter and then manipulate the instance from QML.

Here is what I did so far :

Data.h

class Data : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText)

    public :
        Data() : QObject(), _text("Foo")  { }
        virtual ~Data()                   { }
        Data(const Data & other)          { _text = other._text; }

        QString text() const               { return _text; }
        void setText(const QString & text) { _text = text; }

    private :
        QString _text;
};

Q_DECLARE_METATYPE(Data);

Main.cpp

#include "Data.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Data callBackData;
    QQmlEngine engine;

    QQmlComponent rootComponent(&engine, QUrl::fromLocalFile("CallBack.qml"));
    QObject * rootObj = rootComponent.create();

    QMetaObject::invokeMethod(rootObj, "callMeBack",
                              Q_ARG(QVariant, QVariant::fromValue(callBackData)));

    return app.exec();
}

CallBack.qml

import QtQuick 2.0

Item {
    function callMeBack(data) {
        console.log(data.text)
    }
}

The console outputs "Undefined". Did I do something wrong ?

When changing the function body to console.log(data) it outputs "QVariant(Data)" so why can't I access the text property of data ?

I tried registering Data as a QML type using qmlRegisterType<Data>(); but this does not change anything.

Upvotes: 1

Views: 1892

Answers (1)

Dickson
Dickson

Reputation: 1261

Try pass a QObject pointer instead:

Data *callbackData = new Data;
...
QMetaObject::invokeMethod(rootObj, "callMeBack",
                          Q_ARG(QVariant, QVariant::fromValue(callBackData)));

Not tested, but should work (QML recognize QObject* type).

Upvotes: 2

Related Questions