6
votes

I'm running around in circles about this. Just can't wrap my head around signals and slots.

Just looking for some mechanism that can automatically update my UI when a signal in my C++ occurs.

Example:

I have two labels in Qml that have text: _app.method that returns a value.

I have a button that onClicked runs a Q_INVOKABLE method. That method emits a signal when it's done, eg, fetches geocordinates and updates the values that the above text: assignments rely on.

What I want is SOMETHING to update the text: assignments once those values change.

I just need these signals / slots explained plainly. The only examples in documentation seem to assume ONLY QML or C++ but not a mix of both. The sample code have examples, but not explained specifically in documentation.

If you had plain description, im sure I could adapt to it. Eg, 1: define this in QML, 2: define this in hpp file, 3: define these in cpp file.

I've tried using QObject's setPropery("text","value") but my app crashes when attempting this.

Tell me if i'm wrong...

1) in QML:

Button { 
    id: aButton 
    text: _app.value 
    onClicked: {
        _app.valueChanged.connect(aButton.onValueChanged); 
        _app.value = _app.value + 1;
    } 
    function onValueChanged (val) {
        aButton.text = "New value: " + val;
    }
}

2) in HPP:

    Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
public:
    int value();
    void setValue(int i);
signals:
    void valueChanged(int);
private:
    int m_iValue;

3) in CPP:

int class::value()
{
    return m_iValue;
}

void class::setValue(int i)
{
// name is same as HPP WRITE Q_PROPERTY statement
    m_iValue = i;
    emit valueChanged(m_iValue);
}

So, what happens is that, in QML, the onClick method CONNECTS the signal with a QML Function; which means, now we're listening for a value change, and when it does, that function will be called. THEN, we change the value... since the Q_PROPERTY set the write value to a function called setValue, setValue is called with the new value; internally, m_iValue is changed, and an emit occurs, which tells whoever is listening to valueChanged that there's a new value.

Hey, my QML is listening to that! (via the _app.valueChanged.connect script). So, the QML object (the Button) that was listening to that, has it's onValueChanged function called, with the new value (because of the emit valueChanged(m_iValue).

Please tell me i've figured this out??!?!

1

1 Answers

10
votes

If you are using Q_PROPERTY macro, there's no need to bind onValueChanged signal with a function explicitly to change button's text. And also you need not emit valueChanged signal with m_iValue. Make below mentioned changes in corresponding files

QML:

Button {
    horizontalAlignment: HorizontalAlignment.Center
    verticalAlignment: VerticalAlignment.Center
    id: aButton
    text: _app.value
    onClicked: {
        _app.value = _app.value + 1
    }
}

HPP:

signals:
    void valueChanged();

CPP:

emit valueChanged();