2016-07-08 27 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"; 
     } 
    } 
} 

....そしてここで私はそれが私はそれがない、または望むように動作するかどうかを確認するために使用私の小さなテストハーネスです。

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

あなたは(それぞれ)ToggleButton.qmlにコードとmain.qmlを保存することで、これを実行し、「qmlsceneのmain.qml」を実行することができます。

青色または緑色の四角形をクリックすると、期待どおりに機能することに注意してください。 Rectangleオブジェクトのブール値「lighten」プロパティがオンとオフに切り替えられ、Rectangleの色が変更され、関連付けられたToggleButtonも適切に反応します(「lighten」プロパティがtrueのときは赤、 "プロパティはfalseです)。

これまでのところ、ToggleButton自体をクリックすると、バインディングが壊れています。つまり、ToggleButtonをクリックするとToggleButtonが赤/グレーになりますが、矩形の色は変わりませんそれに続いて、矩形をクリックしてもToggleButtonの状態が変更されなくなりました。

私の質問は、ToggleButtonとそれが追跡しているプロパティとの間に常に双方向の対応関係があるように、これを正しく行うことです。 (QMLアプリケーションの残りの部分にさらされる複雑さを最小限に抑えるために、この機能をToggleButton.qml内にカプセル化したいので、理想的なソリューションはmain.qmlに可能な限り少ないコードを追加することに注意してください)

答えて

1

この問題を解決する一つの方法は、トグルボタンがエイリアスプロパティを使用して、その状態を宣言することですように見えます、通常のプロパティではなく。そうすれば、ToggleButtonの内部プロパティは実際には外部プロパティのエイリアスに過ぎないため、1つの外部プロパティのみが存在するため、双方向バインディングは必要ありません。

ToggleButton.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

興味深い使用ここでは期待どおりに動作QMLコードの更新バージョンです!私はこれの前に使用されていることを見ていませんでした。これまでは、コンポーネントの内部プロパティを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"; 
     } 
    } 
} 
関連する問題