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?
source to share
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.
source to share