2016-07-08 3 views
1

오늘의 QML/QtQuick 연습은 지정된 부울 QML 속성의 상태를 모니터링하도록 인스턴스화 할 수있는 토글 버튼 위젯을 만드는 것입니다. ToggleButton을 클릭하면 해당 속성의 상태가 변경됩니다.부울 속성을 추적/제어하는 ​​QML 토글 버튼을 만드는 방법

// Contents of ToggleButton.qml 
import QtQuick 2.2 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.4 

Button { 
    property bool isActive: false 

    onClicked: { 
     isActive = !isActive; 
    } 

    style: ButtonStyle { 
     background: Rectangle { 
      border.width: control.activeFocus ? 2 : 1 
      border.color: "black" 
      radius: 4 
      color: isActive ? "red" : "gray"; 
     } 
    } 
} 

.... 여기가 내가 내가 그것을가 없거나 원하는 방식으로 작동 여부를 확인하기 위해 사용하는 내 작은 테스트 하네스 :

지금까지 내 ToggleButton의 구성 요소에 대해이 있습니다 :

// Contents of main.qml 
import QtQuick 2.6 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    width: 360 
    height: 360 

    Rectangle { 
     property bool lighten: false; 

     id:blueRect 
     x: 32; y:32; width:64; height:64 
     color: lighten ? "lightBlue" : "blue"; 

     MouseArea { 
     anchors.fill: parent 
     onClicked: parent.lighten = !parent.lighten; 
     } 
    } 

    Rectangle { 
     property bool lighten: false; 

     id:greenRect 
     x:192; y:32; width:64; height:64 
     color: lighten ? "lightGreen" : "green"; 

     MouseArea { 
     anchors.fill: parent 
     onClicked: parent.lighten = !parent.lighten; 
     } 
    } 

    ToggleButton { 
     x:32; y:128 
     text: "Bright Blue Rect" 
     isActive: blueRect.lighten 
    } 

    ToggleButton { 
     x:192; y:128 
     text: "Bright Green Rect" 
     isActive: greenRect.lighten 
    } 
} 

당신은 "qmlscene main.qml"를 실행 한 후 ToggleButton.qml 및 main.qml (각각)에 코드를 저장하고 이것을 실행할 수 있습니다.

파란색 또는 녹색 직사각형을 클릭하면 예상대로 작동합니다. Rectangle 객체의 불린 "lighten"속성은 켜기/끄기로 전환되어 사각형이 색상을 변경하게하고 연관된 ToggleButton도 적절하게 반응합니다 ("lighten"속성이 true 일 때 빨간색으로 바뀌고 "lighten" "속성은 거짓 임).

지금까지 ToggleButton 자체를 클릭하면 바인딩이 끊어졌습니다. 즉, ToggleButton을 클릭하면 ToggleButton이 예상대로 빨간색/회색으로 바뀌지 만 사각형의 색상은 바뀌지 않습니다. 그런 다음, 사각형을 클릭해도 더 이상 ToggleButton의 상태가 변경되지 않습니다.

내 질문은 내가 올바르게 ToggleButton과 추적하는 속성 사이에 양방향 통신을하기 위해이 작업을 수행하는 트릭이 무엇입니까? (이상적인 솔루션은 main.qml에 가능한 한 적은 코드를 추가 할 것이므로이 기능을 ToggleButton.qml 안에 캡슐화하여 나머지 QML 앱에 노출되는 복잡성을 최소화하십시오.)

답변

1

이 문제를 해결하는 한 가지 방법은 ToggleButton의 별칭-속성을 사용하여 상태를 선언하는 것입니다처럼 보이는 , 보통 재산보다는 오히려. 그렇게하면 ToggleButton의 내부 속성은 실제로 외부 속성의 별칭이기 때문에 하나의 외부 속성 만 있으므로 양방향 바인딩이 필요하지 않습니다.

ToggleButton.qml : 여기에 예상대로 작동 QML 코드의 업데이트 버전입니다

// Contents of ToggleButton.qml 
import QtQuick 2.2 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.4 

Button { 
    onClicked: { 
     isActive = !isActive; 
    } 

    style: ButtonStyle { 
     background: Rectangle { 
      border.width: control.activeFocus ? 2 : 1 
      border.color: "black" 
      radius: 4 
      color: isActive ? "red" : "gray"; 
     } 
    }  
} 

main.qml :

// Contents of main.qml 
import QtQuick 2.6 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    width: 360 
    height: 360 

    Rectangle { 
     property bool lighten: false; 

     id:blueRect 
     x: 32; y:32; width:64; height:64 
     color: lighten ? "lightBlue" : "blue"; 

     MouseArea { 
     anchors.fill: parent 
     onClicked: parent.lighten = !parent.lighten; 
     } 
    } 

    Rectangle { 
     property bool lighten: false; 

     id:greenRect 
     x:192; y:32; width:64; height:64 
     color: lighten ? "lightGreen" : "green"; 

     MouseArea { 
     anchors.fill: parent 
     onClicked: parent.lighten = !parent.lighten; 
     } 
    } 

    ToggleButton { 
     x:32; y:128 
     text: "Bright Blue Rect" 
     property alias isActive: blueRect.lighten 
    } 

    ToggleButton { 
     x:192; y:128 
     text: "Bright Green Rect" 
     property alias isActive: greenRect.lighten 
    } 
} 
+0

속성 별칭의 재미있는 사용! 나는 이런 식으로 사용 된 것을 보지 못했습니다. 지금까지 컴포넌트의 내부 속성을 API 화면에 표시하는 데 사용되는 것을 보았습니다.하지만 디자인 문제가 있습니다. ToggleButton은 이제 사용 된 범위의 항목에 의존합니다. 구성 요소 사용에서 속성 별칭을 잊어 버린 경우 QML은 부모 범위에서 해당 별칭을 찾으려고 시도합니다. 그것은 다소 놀라운 버그로 이어질 수 있습니다. 그는 대신 자신이 기대 될 것이다 단지 값을 설정, 그이 isActive 별칭 속성 자신을 추가하는 구성 요소의 사용자에 대한 힌트도 없다. –

5

이것이 작동하지 않는 이유는 고정 값으로 바인딩을 덮어 쓰고 있기 때문입니다. onClicked에 수동으로 값을 할당하면 값으로 바인딩을 덮어 씁니다.

문제는 다음과 같습니다. QML은 지금 2way 바인딩을 지원하지 않습니다. 그러나 하나를 만들려면 몇 가지 트릭이 있습니다. http://imaginativethinking.ca/bi-directional-data-binding-qt-quick/

참고 : isActive 속성을 사용하는 대신 버튼의 선택 상태를 사용하지 않는 이유는 무엇입니까? 이 방법합니다 (documentation에서) 당신이 버튼을 클릭해도, 휴식하지 않습니다 바인딩 :

// Contents of ToggleButton.qml 
import QtQuick 2.2 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.4 

Button { 
    //use the "checked" property instead of your own "isActive" 

    checkable: true 

    style: ButtonStyle { 
     background: Rectangle { 
      border.width: control.activeFocus ? 2 : 1 
      border.color: "black" 
      radius: 4 
      color: checked? "red" : "gray"; 
     } 
    } 
} 
관련 문제