首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TextEdit的属性“`text`”的绑定是如何在QtQuick中工作的?

TextEdit的属性“`text`”的绑定是如何在QtQuick中工作的?
EN

Stack Overflow用户
提问于 2018-05-08 17:00:12
回答 1查看 1.7K关注 0票数 1

我是QML的初学者,我试图遵循QtQuick的标准组件的行为作为指导。

我想以TextEdit的方式实现一个用户输入组件。但是现在我真的很困惑text属性是如何实现的。

假设1:

TextEdit的text是只写的,并且总是显示它的text属性被分配/绑定到什么,如果它存在的话。

实验1

操作

运行QML

代码语言:javascript
运行
复制
Window {
    visible: true
    property string foo: "foo"
    TextEdit { text: foo }
}

在TextEdit中键入任何内容

期望文本总是显示"foo“,不能编辑。

实际的文本随您输入的内容而改变。

结论假设1是错误的。

假设2:

text属性设置为初始化时绑定的对象。一旦用户编辑了它,text就被分配给一个新的值,这个值破坏了绑定。

实验2

操作

运行QML

代码语言:javascript
运行
复制
Window {
    visible: true
    property string foo: "foo"
    TextEdit { id: t1; text: foo; x: 0; }
    TextEdit { id: t2; text: t1.text; x: 100 }
}

在t2中键入某些内容,然后在t1中键入

预期经过t2编辑后,编辑t1将不再改变T2的显示。

实际的 t2可以单独编辑。但是,一旦t1再次被编辑,T2的显示将再次绑定到t1。

结论假设2是错误的。

假设3:

TextEdit有类似于internalText的东西,它代表用户输入的内容。而TextEdit显示的是internalTexttext,两者以最新的更改为准。

实验3

操作

运行QML

代码语言:javascript
运行
复制
Window {
    visible: true
    property string foo: "foo"
    TextEdit { id: t1; text: foo; x: 0; }
    Button { x: 100; onClick: foo = "bar" } // A custom button
}

在t1中键入"blablabla“

单击按钮

在t1中键入"blablabla“

单击按钮,单击按钮,单击该按钮一千次

可以编辑预期的 t1,并在单击按钮时将显示重置为"bar“。

实际在第一次单击时将显示设置为"bar“,然后单击按钮根本不会产生任何效果。

结论假设3是假的。这是.??

还有..。

在多次阅读几次QML引用,特别是属性绑定部分之后,我不知道这种既可以写又能读的属性(也不像角的双向绑定)。我很困惑。

在做了实验3之后,我真的很困惑,有人能解释一下它是如何工作的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-08 23:34:39

绑定更像是元属性,而不是实际值。一旦您从c++方面想象了它是如何工作的,就很容易理解它。

使用信号和插槽实现绑定。简单QML线

代码语言:javascript
运行
复制
text: foo.text

例如,将等效于以下c++代码(简化):

代码语言:javascript
运行
复制
// first: call the getter of text on foo, and the setter on this
this->setText(foo->text());
// second: connect the change signal of foo to this
connect(foo, SIGNAL(textChanged(QString)),
        this, SLOT(setText(QString)));

正如您所看到的,绑定基本上是:“为我分配当前值,每当您的值发生变化时,将我的值更新到您的值”。但是由于"this“仍然有它自己的文本副本,所以您可以通过调用this->setText("something")来修改它,而不破坏绑定(或者用c++术语--信号连接)

这也解释了第二个(和第一个)实验:每当您在GUI中更改t2文本时,t2的内部文本就会被更新。但是,由于绑定仍然存在,所以每次更改t1时,t1都会发出textChanged信号,从而更新t2。

现在是第三个实验,有点棘手。c++代码经过了很大的简化,只解释了发生了什么,而没有解释它是如何工作的。对于第三种情况,我们必须看看qml的javascript方面。更具体的是:如何从javascript创建绑定:

代码语言:javascript
运行
复制
// the qml line
text: foo
// is eqivalent to the js
t1.text = Qt.binding(function(){return foo;})

因此,您并没有真正地将一个值赋给t1.text,而是一个“绑定对象”。( Qt.binding函数具有一些魔力并返回这样的对象)这在内部与上面的c++代码相同,但有一个不同之处。一旦向t1.text分配了一个新值,就像在按钮中那样,旧绑定将与信号连接一起被删除,因为您将绑定对象替换为一个新值。

因此,在按钮中的JS代码中,用值"bar“替换绑定对象,从而销毁它。编辑GUI中的文本不会破坏绑定,因为只有内部值会发生变化,而且实际上没有从QML分配给属性的任何内容。

编辑:现在为什么以后的按钮单击不做任何事情是:按了一次按钮之后,foo被设置为"bar",这会触发textChanged信号,从而改变t1。但是,下一次按下按钮并再次将foo设置为bar时,它什么也不做,因为它已经是"bar“了。您不会通过将其设置为与现在相同的值来更改任何内容。想象一下这样的setter实现:

代码语言:javascript
运行
复制
void setText(QString text) {
    if(this->text == text)
        return;
    this->text = text;
    emit textChanged(text);
}

例如,如果您修改代码,如下所示:

代码语言:javascript
运行
复制
Button { x: 100; onClick: foo = t1.text + "bar" }

它总是会相应地工作并更新foo,因为这个表达式总是为foo生成一个新的值。

我希望我能解释一下你能理解的行为。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50238806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档