如何从 QML 将 属性 绑定到单例对象 属性

How to bind a property to a singleton object property from QML

有一个 question 关于如何从单例对象 属性 绑定到 QML 属性。但是如果我们想将 QML 属性 绑定到单例对象呢?

这里是单例class定义,

class Singleton : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName)
public:
    explicit Singleton(QObject *parent = nullptr);
    QString name() const;
    void setName(const QString &name);
private:
    QString m_name;
};

在 QML 上

property string qmlName: textField.text
TextField {
    id: textField
}

我想将 textField.text 绑定到 Singleton 对象 name 属性。可以使用

等变通方法来绑定它
onQmlNameChanged: {
    Singleton.name = qmlName;
}

但这实际上不会是 Property Binding,因为它是一项作业。

那么对于单例对象有没有更自然的绑定方式属性?

这基本上就是 属性 绑定所做的,至少我认为它是这样做的 - 它将相关变量的 changed() 信号连接到重新评估引用它们的绑定表达式。

所以这实际上是一个绑定:

onQmlNameChanged: {
    Singleton.name = qmlName;
}

如果您只执行一次赋值,您只会遇到问题,但如果它附加到信号,它将按预期从绑定中不断更新。

这与 Singleton.name : qmlName 相同,不幸的是,QML 语法不允许以这种形式进行。因此,就所有意图和目的而言,您确实拥有一个绑定,即使它使用不同的语法来实现它。

事实上,这与 QML 为您暗地里所做的应该没有太大区别。例如绑定:

someProp : anotherProp + yetAnotherProp

是这样实现的:

function unnamed(this) { return this.anotherProp + this.yetAnotherProp }
anotherPropChanged.connect(function(this) { this.someProp = unnamed(this) })
yetAnotherPropChanged.connect(function(this) { this.someProp = unnamed(this) })

显然,手动执行此操作非常麻烦,尤其是当表达式变得更加复杂并引用更多对象时,因此 QML 正在为您完成。

您可以尝试这样分配绑定:

Component.onCompleted: Singleton.name = Qt.binding(function() { return qmlName })

它适用于普通 QML 对象,但不确定它是否适用于单例 class。无论如何,您可以在 "Creating Property Bindings from JavaScript".

部分阅读有关此方法的更多信息