Qt 5.4 / Qml: предотвращение связывания цикла

У меня есть глобальный синглтон «Настройки», в котором хранятся настройки приложения. Когда я пытаюсь запустить следующий код, я получаю QML CheckBox: Binding loop detected for property "checked":

CheckBox {
checked: Settings.someSetting
onCheckedChanged: {
Settings.someSetting = checked;
}
}

Очевидно, почему возникает эта ошибка, но как я могу правильно реализовать эту функцию без цикла привязки? Например. Я хочу сохранить текущее проверенное состояние флажка в настройках синглтона.

Я использую Qt 5.4 и Qml Quick 2.

С Уважением,

7

Решение

Не связывай это. Поскольку флажок не полностью зависит от Setting.someSetting,

Когда пользователь установил флажок, CheckBox.checked меняется само по себе. В то же время привязка свойства больше не действительна. Settings.someSetting не может изменить CheckBox после того, как пользователь нажал на него. Следовательно checked: Settings.someSetting привязка неверна.

Если вы хотите присвоить начальное значение флажку, когда компонент будет готов, используйте Component.onCompleted назначить это:

CheckBox {
id: someSettingCheckBox

Component.onCompleted: checked = Settings.someSetting
onCheckedChanged: Settings.someSetting = checked;
}

Если вы работаете над более сложным сценарием, Setting.someSetting может быть изменено некоторыми другими вещами во время выполнения, и состояние флажка должно быть изменено одновременно. Ловить onSomeSettingChanged сигнал и явно поменял флажок. Отправить значение someSettingCheckBox в Settings только когда программа / виджет / диалог / ххх закончена.

CheckBox { id: someSettingCheckBox }

//within the Settings, or Connection, or somewhere that can get the signal.
onSomeSettingChanged: someSettingCheckBox.checked = someSetting
12

Другие решения

Если вы не хотите делать цикл привязки — не делайте привязку, используйте, например, переменную прокси. Другим простым решением может быть проверка значения:

CheckBox {
checked: Settings.someSetting
onCheckedChanged: {
if (checked !== Settings.someSetting) {
Settings.someSetting = checked;
}
}
}
4

Вы также можете сделать двустороннюю привязку для решения этой проблемы:

CheckBox {
id: checkBox

Binding { target: checkBox; property: "checked"; value: Settings.someSetting }
Binding { target: Settings; property: "someSetting"; value: checkBox.checked }
}
4

Иногда полезно разделять входные и выходные значения в элементе управления. В этом случае элемент управления всегда отображает реальное значение, а также может отображать задержку для пользователя.

CheckBox {
checked: Settings.someSetting
onClicked: Settings.someSetting = !checked
}
1
По вопросам рекламы [email protected]