[SOLVED] Connect QML and C++ via Signals and Slots (QML to C++ and C++ to QML)



  • Greetings,

    I've been busy all day with the topic how to connect QML to C++ via Signals and Slots.

    Now I've finally come up with the solution, and I'd like to share it with the rest of you who have (or will have) the same problem:

    [Qt 5.2.1, QtQuick 2.0, QtCreator 3.0.1]

    myclass.h

    @
    #ifndef MYCLASS_H
    #define MYCLASS_H
    #include <QObject>

    class MyClass : public QObject
    {
    Q_OBJECT
    public:
    MyClass();
    void sendSignal();
    void init(QObject *item);
    public slots:
    void cppSlot(const QString &msg);
    signals:
    void cppSignal(const QString &msg);
    };

    #endif // MYCLASS_H
    @

    myclass.cpp

    @
    #include "myclass.h"
    #include <QDebug>

    MyClass::MyClass()
    {
    QObject();
    //Some stuff
    }

    void MyClass::init(QObject *item)
    {
    connect(item, SIGNAL(qmlSignal(QString)), this, SLOT(cppSlot(QString)));
    }

    void MyClass::cppSlot(const QString &msg)
    {
    qDebug() << "Called the C++ slot with message:" << msg;
    }

    void MyClass::sendSignal()
    {
    emit cppSignal("Hello from C++");
    }
    @

    main.cpp

    @
    #include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include "qquickitem.h"
    #include "myclass.h"
    #include <QQmlContext>

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

    MyClass myClassObject;
    
    QtQuick2ApplicationViewer viewer;
    viewer.rootContext()->setContextProperty("MyClassReference", &myClassObject);
    viewer.setMainQmlFile&#40;QStringLiteral("qml/untitled/main.qml"&#41;&#41;;
    
    QObject *item = viewer.rootObject(&#41;;
    myClassObject.init(item&#41;;
    
    viewer.showExpanded(&#41;;
    
    myClassObject.sendSignal();
    
    return app.exec&#40;&#41;;
    

    }
    @

    main.qml

    @
    import QtQuick 2.0

    Item {
    Connections {
    target: MyClassReference
    onCppSignal: console.log("Called the QML slot with message:", msg)
    }

    id: item
    width: 100; height: 100
    
    signal qmlSignal(string msg&#41;
    
    MouseArea {
        anchors.fill: parent
        onClicked: item.qmlSignal("Hello from QML"&#41;
    }
    

    }
    @

    Note that an extra function init() is needed (that means: the constructor of MyClass should not (cannot) be used to pass the rootObject, because we need to call viewer.rootContext()->setContextProperty("MyClassReference", &myClassObject) before we call viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));, and so we need to create the myClassObject beforehand and call init() afterwards.



  • Dont forget to add disconnect


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.