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
}