Search code examples
c++qtqmlqquickitem

How to hook up to the onClick event of a QML item from C++ side


Scenario:
I have a Qt app which runs on Qt 5.9.4 commercial edition. Its a QtQuick and QML based application which is running on iOS and Android.

I have a QML item on the UI like this:

SomeItem {
    text: qsTr("Some Item")
    objectName: "someitem"
    visible: false
    onClicked: {
        console.log("Some item was clicked")
    }
}

I have a C++ function which can easily control the properties of SomeItem.

void MyCppClass::Func() {

    QQuickItem *someItem = qml_engine->rootObjects()[0]->findChild<QQuickItem*>("someitem");
    someItem->setVisible(true); // this works

    // How to listen to someItem's onClick event here
}

Question:
I want to listen to the onClick event of someItem in a C++ method or a lambda without changing anything in the QML. Basically hook up to the onClick signal signal of someItem from C++ side itself. How can I do it?


Solution

  • The method to use to interact can be dangerous in the general case because the life cycle of the items depends on QML, so make sure it does not happen. Going to your request and I assume that MyCppClass inherits from QObject or a child class you must create a slot and use the old connection syntax:

    *.h

    class MyCppClass: public QObject
    {
    ...
    private slots:
        void on_clicked();
    ...
    };
    

    *.cpp

    void MyCppClass::Func() {
    
        QQuickItem *someItem = qml_engine->rootObjects()[0]->findChild<QQuickItem*>("someitem");
        if(!someItem)
            return;
        someItem->setVisible(true); // this works
        connect(someItem, SIGNAL(clicked()), this, SLOT(on_clicked()));
    
    }
    
    void MyCppClass::on_clicked(){
        qDebug()<<"on clicked";
    }