如何正确地将模型中的 属性 绑定到委托中手工制作的项目中的 属性?
How to correctly bind a property from model to property in hand-made Item in delegate?
我想为任意模型的 ListView
创建一个编辑委托。
在委托中,我想使用我自己的 NeatInput
继承自 TextInput
。 NeatInput
声明自己的 属性 realValue
,将 text
绑定到 realValue
,并且在 textChanged
信号改变 realValue 时使其成为双向的。这按预期工作:
/*NeatInput.qml*/
import QtQuick 2.0
TextInput {
width: 50
property real realValue: 0.0
text: realValue * 2
onTextChanged: {
realValue = Number.fromLocaleString(locale, text) / 2
}
}
现在,它仅用作 ListView
中的委托,在模型的 someValue
上绑定 realValue
,并且出于编辑目的,写入 someValue
在 realValueChanged
:
/*main.qml*/
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
width: 500
height: 500
visible: true
ListView {
id: view
model: ListModel {
ListElement {
someValue: 50
}
}
anchors.fill: parent
delegate: Row {
NeatInput {
realValue: someValue
onRealValueChanged: someValue = realValue
}
SpinBox {
value: someValue
onValueChanged: someValue = value
}
Text {
width: 50
text: someValue
}
}
}
}
Text
用于简单阅读,SpinBox
用于 read/write with standard Item.
但这并不像我预期的那样有效:
- 编辑
SpinBox
仅更新 Text
;
- 编辑
NeatInput
更新 SpinBox
和 Text
。
因此,someValue
上 NeatInput
的绑定在某种程度上被破坏了,但是写入了工作。
如果我从 NeatInput.qml
中删除信号绑定 onTextChanged
,那么:
- 编辑
SpinBox
更新 Text
和 NeatInput
;
- 编辑
NeatInput
更新无。
我应该怎么做才能让所有读者都能看到两位编辑的更新?
一般的经验法则是:赋值中断绑定。每当您这样做时:
onTextChanged: {
realValue = Number.fromLocaleString(locale, text) / 2
}
它破坏了您在此处创建的绑定:
realValue: someValue
所以第一次 text
更改时,realValue
将停止侦听对 someValue
的更新。
Two-way 绑定总是很棘手,因为它们会变成循环。我玩了一分钟你的代码并通过这样做让它工作:
ListView {
id: view
model: ListModel {
ListElement {
someValue: 50
}
}
anchors.fill: parent
delegate: Row {
NeatInput {
realValue: someValue
onRealValueChanged: someValue = realValue
property real someValueCopy: someValue
onSomeValueCopyChanged:
{
realValue = someValueCopy;
}
}
SpinBox {
value: someValue
onValueChanged: someValue = value
}
Text {
width: 50
text: someValue
}
}
}
我想为任意模型的 ListView
创建一个编辑委托。
在委托中,我想使用我自己的 NeatInput
继承自 TextInput
。 NeatInput
声明自己的 属性 realValue
,将 text
绑定到 realValue
,并且在 textChanged
信号改变 realValue 时使其成为双向的。这按预期工作:
/*NeatInput.qml*/
import QtQuick 2.0
TextInput {
width: 50
property real realValue: 0.0
text: realValue * 2
onTextChanged: {
realValue = Number.fromLocaleString(locale, text) / 2
}
}
现在,它仅用作 ListView
中的委托,在模型的 someValue
上绑定 realValue
,并且出于编辑目的,写入 someValue
在 realValueChanged
:
/*main.qml*/
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
width: 500
height: 500
visible: true
ListView {
id: view
model: ListModel {
ListElement {
someValue: 50
}
}
anchors.fill: parent
delegate: Row {
NeatInput {
realValue: someValue
onRealValueChanged: someValue = realValue
}
SpinBox {
value: someValue
onValueChanged: someValue = value
}
Text {
width: 50
text: someValue
}
}
}
}
Text
用于简单阅读,SpinBox
用于 read/write with standard Item.
但这并不像我预期的那样有效:
- 编辑
SpinBox
仅更新Text
; - 编辑
NeatInput
更新SpinBox
和Text
。
因此,someValue
上 NeatInput
的绑定在某种程度上被破坏了,但是写入了工作。
如果我从 NeatInput.qml
中删除信号绑定 onTextChanged
,那么:
- 编辑
SpinBox
更新Text
和NeatInput
; - 编辑
NeatInput
更新无。
我应该怎么做才能让所有读者都能看到两位编辑的更新?
一般的经验法则是:赋值中断绑定。每当您这样做时:
onTextChanged: {
realValue = Number.fromLocaleString(locale, text) / 2
}
它破坏了您在此处创建的绑定:
realValue: someValue
所以第一次 text
更改时,realValue
将停止侦听对 someValue
的更新。
Two-way 绑定总是很棘手,因为它们会变成循环。我玩了一分钟你的代码并通过这样做让它工作:
ListView {
id: view
model: ListModel {
ListElement {
someValue: 50
}
}
anchors.fill: parent
delegate: Row {
NeatInput {
realValue: someValue
onRealValueChanged: someValue = realValue
property real someValueCopy: someValue
onSomeValueCopyChanged:
{
realValue = someValueCopy;
}
}
SpinBox {
value: someValue
onValueChanged: someValue = value
}
Text {
width: 50
text: someValue
}
}
}