2016-08-05 44 views
5

Ich habe eine einfache Liste von CheckBox es, eins für jeden Tag der Woche. Sie hängen vom Wert days ab, einer Ganzzahl, die eine Maske verwendet, und 1 Bit für jede CheckBox.Qt 5.7 QML Warum verschwinden meine CheckBox-Eigenschaftsbindungen?

Zuordnung zu days beide mit der Schaltfläche "Alles löschen" oder die Schaltfläche "Alle einstellen" funktioniert und sie aktualisieren. Sobald jedoch eines der Felder angeklickt wurde, reagieren sie nicht mehr auf Änderungen in der abhängigen Eigenschaft days.

Warum ist das? Werden sie irgendwie ungebunden? Wenn ja, sollte ich sie manuell neu binden, und wenn ja, warum?

Hier ist der Code,

import QtQuick 2.7 
import QtQuick.Controls 1.4 
import QtQuick.Layouts 1.3 

ApplicationWindow 
{ 
    visible: true 
    width: 800 
    height: 400 

    property int days: 0 

    ColumnLayout 
    { 
     Repeater 
     { 
      model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] 
      CheckBox 
      { 
       text: modelData 
       checked: (days & (1<<index)) != false 
       onClicked: 
       { 
        if (checked) days |= (1<<index); 
        else days &= ~(1<<index); 
       } 

      } 
     } 

     Button 
     { 
      text: "clear all" 
      onClicked: days = 0 
     } 

     Button 
     { 
      text: "set all" 
      onClicked: days = 127 
     } 
    } 
} 

, die wie folgt aussieht:

enter image description here

Um das Problem, klicken Sie zuerst auf "setzen alle" und "Alle löschen" zu reproduzieren. Klicken Sie dann auf einige Kontrollkästchen. Klicken Sie dann erneut auf "Alle einstellen" und "Alle löschen". Sie werden feststellen, dass die aktivierten Kontrollkästchen nicht mehr betroffen sind.

danke.

Antwort

1

Wenn Sie das Kontrollkästchen manuell aktivieren, wird die checked-Eigenschaft an einen fest codierten true anstelle des ursprünglichen Ausdrucks: (days & (1<<index)) != false zugewiesen. In ähnlicher Weise erzwingt eine manuelle Aufhebung des Kontrollkästchens die Eigenschaft checked zu einem fest codierten false.

Die Lösung ist einfach die checked Eigenschaft mit Qt.binding wieder zu binden. Ich habe dein Javascript aufgeräumt und deinen Fehler behoben. Bitte schön.

Repeater 
    { 
     model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] 
     CheckBox 
     { 
      function isChecked() { 
       return ((days & (1 << index)) != 0); 
      } 

      text: modelData 
      checked: isChecked() 
      onClicked: 
      { 
       if (checked) { 
        days |= (1<<index); 
       } 
       else { 
        days &= ~(1<<index); 
       } 

       // now rebind the item's checked property 
       checked = Qt.binding(isChecked); 

      } 
     } 
    } 
+0

Vielen Dank! Ihre Antwort funktioniert gut. Ich hatte nicht bemerkt, dass das Zuweisen von "Tagen" die Abhängigkeit von "überprüft" verursachte. Danke für die Erklärung. –

+0

Das Zuweisen von "Tagen" ** führt nicht dazu, dass die Eigenschaft "checked" beschädigt wird. Der tatsächliche Benutzer klickt auf das Kontrollkästchen, damit es unterbrochen wird. Denken Sie so darüber nach. Unmittelbar bevor 'onClicked' aufgerufen wird, ruft Qt' checked = true; 'auf, wodurch Ihre Bedingung überschrieben wird. – selbie

+0

Ja, natürlich hast du recht. es wird durch den tatsächlichen Klick erledigt.Danke fürs klarstellen. –

2

OP hier.

Selbies Antwort ist ziemlich korrekt. Aber ich würde gerne eine Variation veröffentlichen, die ich bevorzuge.

Ich bin zu der Schlussfolgerung gekommen, dass CheckBox es in QT gebrochen sind. Dies liegt daran, dass Sie sie an Ihr Datenmodell binden möchten. und Sie möchten auch auf sie klicken (sonst was ist der Punkt). Wenn Sie darauf klicken, wird die Verbindung zum Modell unterbrochen, so dass es manuell repariert werden muss (siehe Selbies Antwort). Für mich ist das ein gebrochenes Design.

Meine Variation verwendet eine Binding, so dass es nicht jedes Mal neu erstellt werden muss, wenn Sie klicken.

wie folgt aus:

import QtQuick 2.7 
import QtQuick.Controls 1.4 
import QtQuick.Layouts 1.3 

ApplicationWindow 
{ 
    visible: true 
    width: 800 
    height: 400 

    property int days: 0 

    ColumnLayout 
    { 
     Repeater 
     { 
      model: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] 
      CheckBox 
      { 
       text: modelData 
       Binding on checked { value: (days & (1 << index)) != 0 } 
       onClicked: 
       { 
        if (checked) days |= (1<<index) 
        else days &= ~(1<<index) 
       } 
      } 
     } 

     Button 
     { 
      text: "clear all" 
      onClicked: days = 0 
     } 

     Button 
     { 
      text: "set all" 
      onClicked: days = 127 
     } 
    } 
} 

Posting diese Variante zum Wohle anderer.