Search code examples
c++qtqmlqt5qt-signals

Get undefined for receiving a signal with parameter from C++ in QML


I am trying to receive a signal with parameter in QML from C++ QObject class.
The signal looks be triggered but parameter got undefined:

myclass.h

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject * parent = Q_NULLPTR);
    virtual ~MyClass();

    Q_INVOKABLE void monitorResult();

signals:
    void resultChanged(QString newResult);
}

myclass.cpp

#include "myclass.h"

MyClass::MyClass(QObject *parent) : QObject(parent)
{
    
}

MyClass::~MyClass()
{
}

void MyClass::monitorResult()
{
    QString str = "test";
    
    emit resultChanged(str);
}

main.cpp

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

    QQmlApplicationEngine engine;

    QQmlContext *context = engine.rootContext();
    context->setContextProperty("MyClass", new MyClass());

    const QUrl url(QStringLiteral("qrc:/my.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
)

QML

ApplicationWindow {
    id: screen
    visible: true
    width: 1920
    height: 93
    flags: Qt.FramelessWindowHint
    title: qsTr("screen")
    color: "transparent"

    Image {
        id: homeScreen_footer_image
        y: 70
        width: 1920
        height: 93
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 0
        opacity: 1
        source: "images/12_Footer.png"

        Timer {
            interval: 250
            running: true
            repeat: true
            onTriggered: MyClass.monitorResult()
        }

        Connections {
            target: MyClass

            function onResultChanged(result) {
                console.log("onResultChanged triggerred")
                console.log("result: " + result)
            }
        }
    }
}

I get below message on QML stating:

qml: onResultChanged triggerred
qml: newGestureResult: undefined

Can someone help me?

Appreciate in advance.

I try to find solution on Qt documentation and stackoverflow but still no idea what happened.


Solution

  • Replace Connections with this:

            Connections {
                target: MyClass
    
                onResultChanged: (result) => {
                    console.log("onResultChanged triggerred")
                    console.log("result: ", result)
                }
            }
    

    works for me

    Complete example, who is curios to test it. if you will copy that I placed below, I replaced .png with .jpg so be aware of it :)

    // main.cpp
    #include "myclass.h"
    
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        QQmlContext *context = engine.rootContext();
        context->setContextProperty("MyClass", new MyClass());
    
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
        return 0;
    }
    
    // myclass.h
    #ifndef MYCLASS_H
    #define MYCLASS_H
    
    #include <QObject>
    
    class MyClass : public QObject
    {
        Q_OBJECT
    public:
        explicit MyClass(QObject * parent = Q_NULLPTR);
        virtual ~MyClass();
    
        Q_INVOKABLE void monitorResult();
    
    signals:
        void resultChanged(QString newResult);
    };
    
    #endif // MYCLASS_H
    
    // myclass.cpp
    #include "myclass.h"
    #include <QDebug>
    
    MyClass::MyClass(QObject *parent) : QObject(parent)
    {
    
    }
    
    MyClass::~MyClass()
    {
    }
    
    void MyClass::monitorResult()
    {
        QString str = "test";
    
        qDebug() << str;
    
        emit resultChanged(str);
    }
    
    // main.qml
    import QtQuick 2.0
    import QtQuick.Controls 2.0
    import QtQml 2.0
    
    ApplicationWindow {
        id: screen
        visible: true
        width: 1920
        height: 93
        flags: Qt.FramelessWindowHint
        title: qsTr("screen")
        color: "transparent"
    
        Image {
            id: homeScreen_footer_image
            y: 70
            width: 1920
            height: 93
            anchors.left: parent.left
            anchors.leftMargin: 0
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 0
            opacity: 1
            source: "qrc:/footer.jpg"
    
            Timer {
                interval: 250
                running: true
                repeat: true
                onTriggered: MyClass.monitorResult()
            }
    
            Connections {
                target: MyClass
    
                onResultChanged: (result) => {
                    console.log("onResultChanged triggerred")
                    console.log("result: ", result)
                }
            }
        }
    }