QML's autogenerated signal handlers for C++ declared signals

  • Hey all,

    I have a program that I'm working on which uses QML. I'm relatively new to it. I'm finding some features are extremely useful and others are rather confusing. Currently, I'm trying to work with signals which are declared in my "workhorse" class (a QThread which processes data) and QML's signal handlers that are supposed to be automatically created for them.

    The problem is that my QML doesn't seem to see them. Essentially, I'm expecting it to simply look like this:

    class WorkHorse : public QThread
    //...header code...

    void myValueChanged();

    //...more header code...

    //...QML initializations...
    //...QML file header beginning...
    //...QML code...

     onMyValueChanged: someOtherItem.text = someValue;
     //...More QML code...


    Most everything else works in the interactions between QML and my workhorse but all I get is red squigglies for the "onMyValueChanged" part of my code. It hasn't made it or can't see it. If I type "workHorse." and hit CTRL+Space the intellisense will show me "onMyValueChanged" as an option. If I choose it, however, "workHorse" gets redsquigglied. Deleting "workHorse" gets me red squigglies on the signal handler name.

    If you guys could help me change what I need to change I'd appreciate it. Perhaps some includes in the project files or adding Q_INVOKABLE to something or rebuilding or qmake... I'm just not sure what I'm missing. Thanks.

  • You simplified your example a lot, so it is hard to check.
    singal handlers will only be created automatically for properties you define in qml itself. For C++ objects you need to make a Q_PROPERTY and expose that to qml.
    Your signal will not automagically be available in Qml. For that you need to add the instance of your workhorse to rootContext of your qml view. Using @view.rootContext()->setContextProperty("MyHorse", myWorkHorseInstance)@
    That will make MyHorse available in QML.
    Next the signal handler will not exist on an Qml Item.
    You could either use property-binding if you made your myValue also a Q_PROPERTY or they way you try to do in your example you need to add a connection to the earlier added MyHorsecobject.
    Following your example you should add in the Item:
    @Item {
    // ... QML code ...
    Connections {
    target: MyHorse
    onMyValueChanged: console.log("my value changed")

  • Yes, I know that I oversimplified. There were all kinds of things in retrospect that would have helped but I wasn't keen on posting all of the code. I was trying to cut straight to the problem.

    The bindings and Q_PROPERTIES aren't really what I was looking for. I'm aware of those and I wasn't trying to bind one value to another. What I needed to do was compare several different values and change the QML appearance accordingly when a signal is sent.

    What ended up working was the Connections element that you listed here. Inside of that, with my workhorse as my target all of the signal handlers that I was looking for were present. This method allows me to do whatever I want when those signals are sent.

    After some more work the Connections element was thrown out because I found updating and checking values was better implemented with a timer object. Every 250 ms I check and adjust values. This works better for our purposes. Thanks for your help.

Log in to reply