[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(QStringLiteral("qml/untitled/main.qml")); QObject *item = viewer.rootObject(); myClassObject.init(item); viewer.showExpanded(); myClassObject.sendSignal(); return app.exec();
}
@main.qml
@
import QtQuick 2.0Item {
Connections {
target: MyClassReference
onCppSignal: console.log("Called the QML slot with message:", msg)
}id: item width: 100; height: 100 signal qmlSignal(string msg) MouseArea { anchors.fill: parent onClicked: item.qmlSignal("Hello from QML") }
}
@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