2017-07-27 49 views
1

我發現下面的QML組件here信令組件的用戶是結合的性質是不是安全

import QtQuick 2.0 

Rectangle { 
    id: myRect 
    width: 100; height: 100 
    color: "black" 

    MouseArea { 
     id: mouseArea 
     anchors.fill: parent 
     onClicked: myRect.state == 'clicked' ? myRect.state = "" : myRect.state = 'clicked'; 
    } 

    states: [ 
     State { 
      name: "clicked" 
      PropertyChanges { target: myRect; color: "red" } 
     } 
    ] 
} 

讓我們把它稱爲「MyRect.qml」。由於MyRect覆蓋state屬性,綁定到屬性將不起作用:

Item { 
    id: root 

    MyRect { 
     id: inner 

     state: root.state // not safe 
    } 
} 

分配但它會工作:

Item { 
    id: root 

    onStateChanged: inner.state = root.state // safe 

    MyRect { 
     id: inner 
    } 
} 

在另一方面兩者結合並分配將是安全的物業widthMyRect.qml

MyRect.qml的用戶如何知道哪些屬性可以安全地綁定以及哪些不需要檢查源代碼?

+0

你期望什麼?綁定只是單向的,所以當你爲'state'分配一個新的值時,你有兩個相互對立的賦值:外部對象告訴它是''「',內部告訴它是''clicked''。它不能同時存在,所以qml需要做出決定並且取最後一個。 – derM

+0

問題是組件的用戶不知道這個,因爲組件的源代碼是未知的。優選地,QML應該擴展爲具有用於組件創建者發信號的功能。 – uldall

回答

1

你不能。
對於States具體而言,對內部狀態使用根節點狀態是一個壞主意。您應該使用隱藏(內部)對象的狀態,或者您可以直接使用StateMachineStateGroup s

除此之外,您需要使用Binding -objects。那些不能被覆蓋。所以,如果你拿你的例子:

Item { 
    id: root 

    Binding { 
     target: inner 
     property: 'state' 
     value: root.state 
    } 

    MyRect { 
     id: inner 
    } 
} 

每當狀態改變到根狀態時,內部值應該被覆蓋。

一般來說,確保內部綁定不會被覆蓋是更重要的,所以當創建可重用組件時,您應該使用Binding-對象,只要您想將其中一個公開屬性綁定到內部值。

相關問題