2016-03-02 83 views
0

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

这里是单类的定义,

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实际上,因为它是一个任务。

那么是否有更多的自然绑定方式单身对象属性?

+1

实际上不需要qmlName属性。只需''onEditingFinished:{Singleton.name = qmlName}''TextField''就可以完成这项工作。 – rightaway717

+0

是的,不需要qmlName,我们也可以在textField的文本改变信号上编写代码,但这不会是一个属性绑定。 – cavitsinadogru

+0

至于textChanged信号,除了“实时搜索”之外,您可能不想使用它,否则为什么每个字母的发送信号都会发生变化,如果您需要整个单词。至于属性绑定,@ddriver几乎解释了它,所以在这种情况下,它只是关于你喜欢单词“绑定”。如果它在引擎盖下也一样,那么它有什么区别? – rightaway717

回答

1

你可以试着分配这样的绑定:

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

它适用于正常的QML对象,不知道它的工作原理与一个单独的类,虽然。无论如何,您可以在"Creating Property Bindings from JavaScript"部分阅读有关此方法的更多信息。

0

这实质上是属性绑定所做的事情,至少我假设它是它所做的 - 它连接相关变量的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正在为你做。

+0

我不确定这是属性绑定。我不这么认为,因为qmlName必须更改,所以要执行的行是Singleton.name = qmlName。但另一方面,当我们绑定一个属性时,绑定的属性也会被绑定的属性初始化。所以要模仿属性绑定,我们也必须解决这个问题。其次,这使得qmlName和Singleton.name之间存在永久关系,但是在属性绑定中,这种关系是脆弱的,我的意思是如果我们将任何东西赋值给绑定属性,属性绑定将被打破。 – cavitsinadogru

+0

嗯,是这样,它不会被安排在组件完成的自动评估,你必须手动完成。是的,你也必须手动断开连接,只有当你使用'signal.connect(namedFoo)'而不是'onSignal:expr''时才可以调用'signal.disconnect(namedFoo)'。手动进行绑定意味着也要手动管理它。如果费利克斯提出的解决方案的工作,你应该去它,因为它会自动为你做所有的东西。 – dtech

+0

是的,好像@Felix解决方案更加准确。感谢您加入线程。 – cavitsinadogru

相关问题