2016-08-05 45 views
5

Mam prostą listę CheckBox es, jedną na każdy dzień tygodnia. Zależą one od wartości days, liczby całkowitej za pomocą maski, 1 bit za każdy CheckBox.Qt 5.7 QML Dlaczego moje powiązania właściwości CheckBox znikają?

Przypisanie do days zarówno za pomocą przycisku "wyczyść wszystko" lub przycisku "ustaw wszystko" działa i są one aktualizowane. Jednak po kliknięciu dowolnego z pól nie reagują one już na zmiany w zależnej właściwości days.

Dlaczego tak jest? Czy w jakiś sposób stają się niezwiązane? Jeśli tak, czy powinienem je ręcznie ponownie powiązać, a jeśli tak, dlaczego?

Oto kod,

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 
     } 
    } 
} 

który wygląda następująco:

enter image description here

odtworzyć problem, najpierw kliknij na "set all" i "Clear All". następnie kliknij pola wyboru. Następnie ponownie kliknij "set all" i "clear all". Zobaczysz, że pola, które zaznaczyłeś, nie są już dotknięte.

dzięki.

Odpowiedz

1

Po ręcznym kliknięciu tego pola wyboru właściwość checked zostaje ponownie przypisana do zakodowanej na stałe nazwy true zamiast oryginalnego wyrażenia: (days & (1<<index)) != false. Podobnie ręczne usunięcie zaznaczenia tego pola powoduje wymuszenie właściwości checked na zakodowanym na stałe kodzie false.

Rozwiązaniem jest po prostu ponowne powiązanie właściwości checked przy użyciu Qt.binding. Oczyściłem twój javascript i naprawiłem twój błąd. Zapraszamy.

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

Dziękuję bardzo! Twoja odpowiedź działa jak smakołyk. Nie zdawałem sobie sprawy, że przypisanie do 'dni' spowodowało, że zależność" sprawdzonego "została przerwana. Dziękuję za wyjaśnienie. –

+0

Przypisanie do 'dni' ** nie oznacza, że ​​właściwość' checked' zostanie złamana. Faktyczny użytkownik klika na pole wyboru powoduje, że jest on uszkodzony. Pomyśl o tym w ten sposób. Tuż przed wywołaniem 'onClicked', Qt wywołuje' checked = true; 'Tym samym przesłonię twoje warunkowe. – selbie

+0

Oczywiście, masz rację. odbywa się poprzez rzeczywiste kliknięcie.dzięki za wytłumaczenie. –

2

OP tutaj.

Odpowiedź Selbiego jest całkiem poprawna. Ale chciałbym opublikować wariant, który preferuję.

Doszedłem do wniosku, że CheckBox es są uszkodzone w QT. Dzieje się tak dlatego, że będziesz chciał powiązać je z modelem danych. , a Ty też chcesz je kliknąć (w przeciwnym razie, o co chodzi). Kliknięcie na nie powoduje przerwanie połączenia z modelem, więc musi zostać naprawione ręcznie (patrz odpowiedź Selbiego). Dla mnie to zepsuty projekt.

Moja odmiana używa numeru Binding, więc nie musi być ponownie wprowadzana za każdym razem, gdy klikniesz.

tak:

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 
     } 
    } 
} 

zamieszczaniu te różnice na korzyść innych.