2015-01-31 10 views
6

Ich habe eine globale Singleton "Einstellungen", die Anwendung Einstellungen hält. Wenn ich versuche, den folgenden Code ausführen bekomme ich ein QML CheckBox: Binding loop detected for property "checked":Qt 5.4/Qml: Verhindern Bindung Schleife

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

Es ist offensichtlich, warum dieser Fehler auftritt, aber wie kann ich diese Funktion korrekt ohne Bindungsschleife implementieren? Z.B. Ich möchte den aktuellen Check-Zustand des Kontrollkästchens in den Einstellungen Singleton speichern.

Ich bin mit Qt 5.4 und QML Schnell 2.

Grüße,

+0

Wenn Sie keine Bindeschleife erstellen möchten - machen Sie keine Bindung. Verwenden Sie beispielsweise eine Proxy-Variable. –

+0

Meinst du eine Eigenschaft außerhalb der Checkbox, die den Wert enthält? – Hyndrix

+0

Ja, ich meinte das. –

Antwort

10

Binden Sie es nicht. Da das Kontrollkästchen nicht vollständig auf Setting.someSetting angewiesen ist. Wenn ein Benutzer auf das Kontrollkästchen geklickt hat, wird CheckBox.checked von selbst geändert. Gleichzeitig ist die Eigentumsbindung nicht mehr gültig. Settings.someSetting kann die CheckBox nicht ändern, nachdem sie vom Benutzer angeklickt wurde. Daher ist die checked: Settings.someSetting Bindung falsch.

Wenn Sie einen Anfangswert zu dem Kontrollkästchen zugewiesen werden soll, wenn die Komponente bereit ist, verwenden Sie Component.onCompleted es zuzuweisen:

CheckBox { 
    id: someSettingCheckBox 

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

Wenn Sie auf einem komplexeren Szenario arbeiten, werden die Setting.someSetting kann geändert durch einige andere Dinge während der Laufzeit und der Zustand des Kontrollkästchens muss gleichzeitig geändert werden. Catch onSomeSettingChanged Signal und explizit das Kontrollkästchen geändert. Senden Sie den Wert someSettingCheckBox nur dann an Settings, wenn das Programm/Widget/dialog/xxx beendet ist.

CheckBox { id: someSettingCheckBox } 

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

Wenn Sie nicht möchten, dass eine bindende Schleife machen - keine Bindung machen, einen Proxy-Variable verwenden, zum Beispiel . Andere einfache Lösung kann sein, den Wert zu überprüfen:

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

Interessanterweise funktioniert dies die meiste Zeit, aber mit den Qt Quick Controls 2 verursacht dies manchmal auch eine Bindeschleife. – Hyndrix

3

Sie können auch Zweiwege machen Bindung dieses Problem zu beheben:

CheckBox { 
    id: checkBox 

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

Manchmal ist es sinnvoll, Ein- und Ausgangswerte in der Steuerung zu trennen. In diesem Fall zeigt die Steuerung immer den tatsächlichen Wert an und sie kann dem Benutzer auch eine Verzögerung anzeigen.

CheckBox { 
    checked: Settings.someSetting 
    onClicked: Settings.someSetting = !checked 
} 
Verwandte Themen