Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property binding not updating

I am continuously getting data for my application as it runs, but I am having a bit of trouble displaying the data once I have read it in and stored it in a map.

When I try to display the data in the QML, it simply displays zero, despite the fact that I can see it updating in the application output.

I access the value in QML using property bindings (I was under the impression that these led headingSensor to be updated whenever carData.headingSensor changed?):

property int headingSensor: carData.headingSensor
Text {  text: "Heading: " + headingSensor }

In my data class I have:

Q_PROPERTY(int headingSensor READ getHeadingSensor NOTIFY headingSensorChanged)
        int headingSensor;

In the c++ implementation I originally had:

    int data::getHeadingSensor(){
        return data.value(heading)[headingSensorReading];
    }

Where it returns the value in the map which is being updated with the incoming information.

This I realized, probably doesn’t work, because the property is dependent upon the headingSensor variable, which is itself not being updated despite the correct value being returned. So, I thought if I changed it to update the headingSensor value and return that it might work.

So in my data aquisition logic I wrote a method to update the variables as well.

                data.insert(key, value);
                updateVariables();
            }
        }
    }
    void data::updateVariables(){
        headingSensor = data.value(heading)[headingSensorReading];
    }
    int data::getHeadingSensor(){
        return headingSensor;
    }

While this led to the headingSensor variable being updated in addition to the value in the map, the correct value is still not displayed in the QML display. It simply displays 0 (its default value when it is initially displayed since it has not gotten a value from incoming data yet).

So, I am wondering, how can I get the value of sensorHeading displayed in the QML to update as the value of it and/or the value in the map changes in C++? Do I need to do something like:

Connections {
    target: carData
    onSensorHeadingChanged: updateValues
}

EDIT: Trying something like this, the onSensorHeadingChanged never fires. I am not sure why, since the value of sensorHeading clearly changes as I watch it in the application output


Connections{
     target: carData
     onHeadingSensorChanged: console.log("It's noting the change!")
}
like image 949
user1475920 Avatar asked Feb 20 '23 19:02

user1475920


1 Answers

It is the responsibility of the C++ element writer to emit headingSensorChanged() in order to cause the binding to be updated.

This tutorial is a good place to start when implementing a C++ element.

In your case you need to do something like this:

void data::updateVariables(){
    int sensorReading = data.value(heading)[headingSensorReading];
    if (headingSensor != sensorReading) {
        headingSensor = sensorReading;
        emit headingSensorChanged();
    }
}

Note that we don't emit the change notifier unless there really is a change. This prevents needless JS evaluations, and also removes the possibility of binding loops.

like image 73
MartinJ Avatar answered Mar 11 '23 00:03

MartinJ