How to reevaluate a qml property related C ++ function when a dependent property changes?

I want to bind a C ++ class method to a QML component property and override it when the dependent property changes. The following QML component does what I want:

// Converter.qml:
import QtQuick 2.0

QtObject {
    property double rate: 1
    function exchange(amount) { return amount * rate }
}

      

If I assign the result of a function to a exchange

property like

Text { text: converter.exchange(100) }

      

The Text element will automatically update when changed rate

. This works with a QML component, but I don't know how to do it with a C ++ class.

I would like to implement a functionally equivalent class in C ++:

#include <QObject>

class Convert : public QObject
{
    Q_OBJECT
    Q_PROPERTY(double rate READ rate WRITE setRate NOTIFY rateChanged)

public:
    explicit Convert(QObject *parent = 0)
        : QObject(parent), m_rate(1.0)
    { }

signals:
    void rateChanged();

public slots:
    double exchange(double amount) { return m_rate * amount; }

    double rate() { return m_rate; }

    void setRate(double r) {
        m_rate = r;
        emit rateChanged();
    }

private:
    double m_rate;
};

      

The property is rate

accessible from QML, but changing it does not signal the QML engine to re-evaluate the "exchange".

Here is my main.qml:

// main.qml
import QtQuick 2.1
import QtQuick.Controls 1.1
import Utils 1.0

ApplicationWindow {
    width: 300; height: 200
    visible: true

//    Converter { id: converter; rate: rateField.text }
    CppConverter { id: converter; rate: rateField.text }
    Column {
        TextField { id: rateInput; text: '0.41' }
        TextField { id: amountInput; text: '100.00' }
        Text { id: output; text: converter.exchange(amountField.text).toFixed(2) }
    }
}

      

If I opt in CppConverter

, the output will be updated when I change amountInput

, but if you do not change rateInput

. If I comment out the QML Converter item, the update works fine.

With a QML converter, the QML runtime determines the dependency on the rate property and re-evaluates the exchange function when the rate changes. How can I tell QmlEngine to do the same in the C ++ version?

+3


source to share


1 answer


There is currently no way to do this.

I don't think it is good practice to rely on function re-evaluation as it is good practice. You must either explicitly call it when needed:

Connections {
    target: converter
    onRateChanged: output.text = converter.exchange(amountField.text)
}

      



Or convert exchange () to a property and approach it declaratively instead of imperatively (code incomplete or tested):

class Convert : public QObject
{
    // ...
    Q_PROPERTY(double amount READ amount WRITE setAmount NOTIFY amountChanged)
    Q_PROPERTY(double exchange READ exchange NOTIFY exchangeChanged)

    // ...

public:
    double exchange() { return m_rate * m_amount; }

private:
    double m_rate;
    double m_amount;
};

      

Then you will need to emit various * Modified signals, etc. in appropriate places.

+3


source







All Articles