Search code examples
c++qtqmlqt5qt-signals

Receiving a signal with parameter from C++ class in QML


I would like to receive a signal from a C++ QObject class in QML I have read a guide from :

https://doc.qt.io/archives/qt-4.8/qtbinding.html#receiving-signals

but i am having trouble getting results here is my sample code:

myclass.h

class myClass : public QObject
 {
  Q_OBJECT

  public:

   explicit myClass(QObject *parent = nullptr);

   Q_INVOKABLE void incrementNumber(){
       number++;
       qDebug()<<number;
       emit numberChanged(number);
   }

  signals:
     Q_INVOKABLE int numberChanged(int &number);
  public slots:

  private:
     int number = 0;
  };

main.cpp

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QScopedPointer<myClass> myclass (new myClass);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    engine.rootContext()->setContextProperty("myclass",myclass.data());
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

QML

 Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    Button{
        onClicked: {
            myclass.incrementNumber()
        }
    }
    Text {
        id: texty
        text: "0"
    }

    Connections{
        target: myclass
        onNumberChanged: {
            texty.text = number
            console.log ("number Changed to: " + number)
        }
    }
}

I get an error on QML stating

Error: Cannot assign [undefined] to QString"

So I am guessing that i am doing the connections wrong.


Solution

  • You have the following errors:

    • According the docs the signals: They can never have return types (i.e. use void). On the other hand it does not make sense that it is Q_INVOKABLE, and finally you must pass the value of the integer, not the reference.

    • You have to export the QObject before loading the QML.

    *.h

    signals:
        void numberChanged(int number);
    

    main.cpp

    ...
    QQmlApplicationEngine engine;
    
    engine.rootContext()->setContextProperty("myclass", myclass.data());
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    ...