Receiving C++ signal in QML
-
I have an urgent need to receive a signal in qt quick that originates in c++. I am using version 5.7.
I have a class QmlMain instantiated in main.cpp and registered
qmlRegisterType<QmlMain>("Main", 1, 0, "QmlMain");
...
QmlMain *qmlMain = new QmlMain();I have a signal in qmlMain that is being emitted and can be detected with a test slot in qmlmain
qmlmain.h
signals:
void bootStrapDone();main.qml
import Main 1.0
..
//expose c++ code behind
QmlMain {
id: qmlmainonKeyModelChanged:{ //only getting this after a click console.log("Model changed!")
// window.reloadModel = true;
drawer.close()
titleLabel.text = Title
stackView.replace(Source)
}
onBootStrapDone: {
console.log("done")
}
}The onBootStrapDone slot is never called but the onKeyModelChanged slot is. I tried putting the slot in a connections block in qml, using a QObject::connect in main (although I may have not had the syntax correct) and using a jscript function in qml all without success. Again I know the signal is being emitted in c++.
Please help
Thanks -
Hi! The object in C++ (
qmlMain
) and the object in QML (id: qmlmain
) are two different instances. -
@Wieland
Thanks for that.
So how do I make the connection then between the C++ instance and the qml instance?Or more generally, how do I make the C++ trigger things in the qml. I know the opposite direction uses qml signal and Q_Invokable.
Thank you!
-
Hi,
Simething's not clear: do you want to have one object created in C++ that you want to interact with ? Or do you want to interact with the one you created in QML ?
-
I'm pretty sure you want to interact with a C++ object (already instanced) from QML?
If so, take a read of:
http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html#registering-an-instantiable-object-type- register your class type with qml:
qmlRegisterType<...>
- Instanciate your class
- get your QML engines' context (my example is root but I believe you can target).
- call setContextProperty using the context:
QQmlContext *context = m_Engine.rootContext(); context->setContextProperty(QStringLiteral("ClassInstanceCpp"), &m_ObjectInstance);
Sorry if I misunderstand but hopefully gets you moving again...
-
@6thC You don't have to register the type if you want to interact in QML with an object created in C++. You just need to setContextProperty. Registering is for defining classes in C++ and then creating objects in QML (or using certain other features of C++ classes). Obviously @sly110 has registered the type, but if you 6thC are correct (and I presume you are) he wants to create an object in C++ and receive a signal sent in C++. For that a context property object is enough. It can be used as a global object in QML, for example:
Connections{ target: qmlmain onBootStrapDone: {} }
-
Yes I am trying to instantiate from c++ and access from qml. I did not realize that qml was actually instantiating. I thought it was just being referenced. But as I think about it more that implies that there is only one instance of the c++ class since register only takes a class name (i.e as if the class was static).
Also, it appeared that qml preferred constructors with now parameters. I guess I can now instantiate my qmlMain class with constructor parameters. ???
I think I understand the problem now thanks to all the help and will try it later today and probably mark as solved.
Thank you all!
-
@Eeli-K Cheers mate.
I appreciate being corrected/set on track - I had suspected as such but I guess that got stuck from my own trial and error.
I'm not even a year using Qt now and after a decade of no C++ picking that up again too - a fair bit has changed. I love auto range for loops :-)