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

72 Views Asked by At

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.

2

There are 2 best solutions below

0
tzorake On BEST ANSWER

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)
            }
        }
    }
}
0
Arya On

i did get the str from the onResultChanged function. here is my code:

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();
public Q_SLOTS:
    void monitorResult();

Q_SIGNALS:
    void resultChanged(QString newResult);
};

#endif // MYCLASS_H

MyClass.cpp

#include "myclass.h"

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

}

MyClass::~MyClass()
{
}

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

    Q_EMIT resultChanged(str);
}

main.cpp

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

    QQmlApplicationEngine engine;

    qmlRegisterType<MyClass>("app.MyClass", 1, 0, "MyClass");

    gst_init (&argc, &argv);
    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();
}

QML

import app.MyClass 1.0

ApplicationWindow {
    id: mainItm
    MyClass{
        id: myClass
    }
    
    Timer {
        interval: 250
        running: true
        repeat: true
        onTriggered: myClass.monitorResult()
    }
    
    
    Connections {
        target: myClass
        
        function onResultChanged(result) {
            console.log("onResultChanged triggerred")
            console.log("result: " + result)
        }
    }
}