Nominate our 2022 Qt Champions!

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

    void bootStrapDone();

    import Main 1.0
    //expose c++ code behind
    QmlMain {
    id: qmlmain

        onKeyModelChanged:{  //only getting this after a click
            console.log("Model changed!")

    // window.reloadModel = true;
    titleLabel.text = Title
    onBootStrapDone: {

    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

  • 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!

  • Lifetime Qt Champion


    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:

    1. register your class type with qml:
    1. Instanciate your class
    2. get your QML engines' context (my example is root but I believe you can target).
    3. 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:

    target: qmlmain
    onBootStrapDone: {}

  • @SGaist

    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!

  • @sly110
    That was it! And I learned more about QML in the process. 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 :-)

Log in to reply