我更喜欢这个解决方案
// Within the model
Q_PROPERTY(bool someSetting READ getSomeSetting WRITE setSomeSetting NOTIFY someSettingChanged)
void SettingsModel::setSomeSetting(bool checkValue) {
if (m_checkValue != checkValue) {
m_checkValue = checkValue;
emit someSettingChanged();
}
}
// QML
CheckBox {
checked: Settings.someSetting
onCheckedChanged: Settings.someSetting = checked
}
诀窍是你emit
在模型中使用 if 检查来保护它。这意味着您仍然会得到一个绑定循环,但只有一个,而不是无限的。当 if check 返回 false 从而不会发出继续循环时,它会停止。这个解决方案非常干净,您不会收到警告,但您仍然可以获得绑定的所有好处。
我想谈谈其他解决方案的局限性
CheckBox {
Component.onCompleted: checked = Settings.someSetting
onCheckedChanged: Settings.someSetting = checked;
}
在此解决方案中,您将失去绑定。它只能在创建时具有默认设置并由用户更改。如果您扩展程序以使其他事物更改模型中的值,则此特定视图将无法反映这些更改。
Settings {
id: mySettings
onSomeSettingChanged: checkBox.checked = someSetting
}
CheckBox {
id: checkBox
onCheckedChanged: mySettings.someSetting = checked
}
这个解决方案被提到来解决这些问题,但从未写出来。它功能齐全。模型更改被反映,用户可以更改数据,并且没有绑定循环,因为没有绑定;只有两个离散的分配。(x: y
是绑定,x = y
是赋值)
这有几个问题。首先是我认为它丑陋和不雅,但这可以说是主观的。这里看起来不错,但如果你有一个模型在这个视图中代表 10 个东西,这就会变成信号意大利面条。更大的问题是它不适用于代表,因为它们只是按需存在。
例子:
MyModel {
id: myModel
// How are you going to set the check box of a specific delegate when
// the model is changed from here?
}
ListView {
id: listView
model: myModel.namesAndChecks
delegate: CheckDelegate {
id: checkDelegate
text: modelData.name
onCheckStateChanged: modelData.checkStatus = checked
}
}
你实际上可以做到。我已经编写了自定义 QML 信号和连接来执行此操作,但代码复杂性让我想投掷,更糟糕的是,您可能会在不需要时强制创建委托。