Qt 5.4/ Qml: предотвращение цикла привязки
у меня есть глобальные одноэлементные "настройки", которые содержат настройки приложения. Когда я пытаюсь запустить следующий код, я получаю QML CheckBox: Binding loop detected for property "checked"
:
CheckBox {
checked: Settings.someSetting
onCheckedChanged: {
Settings.someSetting = checked;
}
}
очевидно, почему эта ошибка возникает, но как я могу правильно реализовать эту функцию без привязки петли? Например. Я хочу сохранить текущее проверенное состояние флажка в настройках singleton.
Я использую Qt 5.4 и QML Quick 2.
С уважением,
4 ответов
не связывайте его. Потому что флажок не полностью зависит от Setting.someSetting
.
когда пользователь щелкнул флажок,CheckBox.checked
изменяется сам по себе. В то же время привязка свойства больше не является допустимой. Settings.someSetting
не удается изменить флажок после нажатия пользователем. Следовательно,checked: Settings.someSetting
привязка неправильная.
если вы хотите присвоить начальное значение флажка, когда компонент будет готов, используйте Component.onCompleted
, чтобы назначить его:
CheckBox {
id: someSettingCheckBox
Component.onCompleted: checked = Settings.someSetting
onCheckedChanged: Settings.someSetting = checked;
}
если вы работаете над более сложным сценарием, то Setting.someSetting
могут быть изменены некоторыми другими вещами во время выполнения, и состояние флажка необходимо изменить одновременно. Лови onSomeSettingChanged
сигнал и явно изменил флажок. Отправить значение someSettingCheckBox
to Settings
только после завершения программы/виджета/диалога/xxx.
CheckBox { id: someSettingCheckBox }
//within the Settings, or Connection, or somewhere that can get the signal.
onSomeSettingChanged: someSettingCheckBox.checked = someSetting
Если вы не хотите делать цикл привязки - не делайте привязку, используйте переменную прокси, например. Другим простым решением может быть проверка значения:
CheckBox {
checked: Settings.someSetting
onCheckedChanged: {
if (checked !== Settings.someSetting) {
Settings.someSetting = checked;
}
}
}
вы также можете сделать двустороннюю привязку для решения этой проблемы:
CheckBox {
id: checkBox
Binding { target: checkBox; property: "checked"; value: Settings.someSetting }
Binding { target: Settings; property: "someSetting"; value: checkBox.checked }
}
иногда полезно разделить входные и выходные значения в элементе управления. В этом случае элемент управления всегда отображает реальное значение, а также может отображать задержку для пользователя.
CheckBox {
checked: Settings.someSetting
onClicked: Settings.someSetting = !checked
}