pix*_*ase 5 c++ binding qt signals-slots qml
我想将 C++ 类的方法绑定到 QML 组件属性,并在依赖属性更改时重新评估它。以下 QML 组件执行我想要的操作:
// Converter.qml:
import QtQuick 2.0
QtObject {
property double rate: 1
function exchange(amount) { return amount * rate }
}
Run Code Online (Sandbox Code Playgroud)
如果我将exchange函数的结果分配给这样的属性,
Text { text: converter.exchange(100) }
Run Code Online (Sandbox Code Playgroud)
Text 元素会在rate更改时自动更新。这适用于 QML 组件,但我不知道如何使用 C++ 类来实现。
我想在 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;
};
Run Code Online (Sandbox Code Playgroud)
该rate属性可从 QML 访问,但更改它不会向 QML 引擎发出信号,表明应该重新评估“交换”。
这是我的 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) }
}
}
Run Code Online (Sandbox Code Playgroud)
如果我启用CppConverter,当我改变了输出被更新amountInput,但不是当我改变rateInput。如果我在 QML Converter 元素中添加注释,则更新工作正常。
使用 QML 转换器,QML 运行时识别对汇率属性的依赖,并在汇率改变时重新评估交换函数。我如何向 QmlEngine 指示在 C++ 版本中做同样的事情?
目前没有办法做到这一点。
不过,我认为依赖像这样重新评估的函数不是一个好的做法。您应该在必要时显式调用它:
Connections {
target: converter
onRateChanged: output.text = converter.exchange(amountField.text)
}
Run Code Online (Sandbox Code Playgroud)
或者将 Exchange() 转换为属性,并以声明方式而不是命令方式处理它(代码未完成或测试):
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;
};
Run Code Online (Sandbox Code Playgroud)
然后,您需要在适当的位置发出各种 *Changed 信号等。