2015-05-06 47 views
0

這很奇怪,因爲我在另一個QML文件中使用了幾乎相同的模式,並且它能夠正常工作!我相信我不會在任何地方重新分配價值(我知道的唯一可以讓屬性變爲靜態的東西)! 我有這樣的事情(這是一個簡單的例子,可能按預期工作):在我爲什麼Qt QML沒有正確綁定屬性?

Item { 
    property bool isExpanded: false 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      isExpanded = !isExpanded 
      console.log(isExpanded) 
      console.log(myId.visible) 
     } 
    } 
    MyCustomItem { 
     id: myId 
     visible: isExpanded 
     // other stuff 
    } 
} 

IsExpanded更改,請單擊但Item知名度始終保持不變!而且我還有很多其他屬性(例如height: isExpanded ? someval : 0),這些屬性也不會改變!如果我總是手動更改所有內容,那麼它的作品有點類似,但那又有什麼意義?而在另一個QML中,我使用了一個類似的模式,它在那裏工作!

但是!如果我把,例如onDoubleClicked /另一個按鈕按: myId.visible = Qt.binding(function() {return isExpanded}) 它的工作原理,因爲它應該!所以,由於某些未知的原因,當它應該在常規財產聲明(visible: isExpanded)中時,它不會「綁定」它們。

所以問題是,我是否真的需要明確告訴Qt綁定屬性使其工作?

編輯:爲了說清楚:我確定我不會在任何地方重新指定可見的屬性。我確認了它。儘管qml大小隻有大約100行,但我使用ctrl + f來查找任何提及的可見內容,除了已經提到的內容外,沒有發現任何內容。 如果有更可靠的方法來說明什麼來自/檢查某處或某些地方可能的重新分配,請告訴。

+1

確實「其他的東西」或任何其他分配給myId.visible並打破綁定?這是我能想到的唯一的事情。或MyCustomItem聲明它自己的可見屬性,並且impl包含一個錯誤。 –

+0

不,它沒有。如果有什麼會破壞綁定不會也打破「硬編碼」綁定太myId.visible = Qt.binding(function(){return isExpanded})? MyCustomItem只是其中包含其他內容的Item {}。它本身並不使用可見屬性。唯一我「可能」重新分配的是item id(它在qml文件中有它自己的內部id,但是因爲我的問題qml中有兩個 - 它們分配了不同的id) –

+0

我不喜歡你的態度。你需要習慣於你不具備世界上所有的知識,如果有經驗的人說你只是打破了束縛,那就意味着你做到了。它可能是世界上最反直覺的錯誤,但是,是誰設計的呢?也許你不完全理解你使用的機制或語言的目的。 –

回答

0

我發現問題了!非常不明顯(沒有發現任何地方記錄),它失敗了。 的問題是,包含MyCustomItem與外booleal屬性isExpanded的相同名稱的屬性,因此在這樣的代碼:

MyCustomItem { 
    id: myId 
    visible: isExpanded 
// other stuff 
} 

isExpanded是從MyCustomItem。但沒有任何跡象。那麼,現在我知道這可能會發生,如果再次發生,可能會發現它,但這真的是違反直覺。如果它不是我的物品,但是別人的,我不知道它有這樣的屬性? Qt創建者至少可能會對可能的含糊之處發出警告。

+1

它並不違反直覺,它遵循與每種語言相同的範圍規則。在C中做這個沒有什麼不同:'{int a = 0; {int a = 1; int b = a;}}'並且期望'b'爲0 – cmannett85

+0

@ cmannett85它違反直覺,因爲語法不同。當您聲明時,您不會看到項目的「內部」。這更像是如果你有(實際上沒有,但它看起來和使用)'int a = 0; b項; b.setC(a)'如果setC分配給某些內部(到b)屬性a而不是我們所知道的,那將是違反直覺的。 –

+1

語法不同,範圍的語義不是(至少從這個pov)。 Qt Creator無法警告某些可行的事情,即使在大多數情況下它可能是一個痛苦的脖子。 – BaCaRoZzo

1

所以問題是,我是否真的需要明確告訴Qt綁定屬性使其工作?

是的。

當聲明屬性時,可以使用綁定語法,例如visible: isExpanded。但是使用普通的JavaScript語法(即賦值運算符)在命令式代碼中設置屬性將會破壞任何現有的綁定並覆蓋該屬性的值。如果要在命令代碼中明確設置屬性綁定,請使用Qt.binding()方法(docs)。

儘管您的實際問題是由於QML的範圍規則受害者。您MyCustomItem類型都有isExpanded屬性,所以當你聲明:

MyCustomItem { 
    id: myId 
    visible: isExpanded 
    // other stuff 
} 

你實際上結合visibleMyCustomItem::isExpanded。因此,要明確您所指的是哪個isExpanded

Item { 
    id: base 
    property bool isExpanded: false 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      isExpanded = !isExpanded 
      console.log(isExpanded) 
      console.log(myId.visible) 
     } 
    } 
    MyCustomItem { 
     id: myId 
     visible: base.isExpanded 
     // other stuff 
    } 
} 
+0

有趣的一點(和有趣的功能!)。 – BaCaRoZzo

+0

這不是我的問題的答案!看看我的代碼,請再讀一遍!問題是綁定語法**不工作**出於某種原因(儘管必要的,使用Qt.binding()確實有效)。我不明白爲什麼。 –

+1

@DanM。 「看看我的代碼,請再讀一遍!」你的代碼完美地工作。綁定不會失敗(沒有錯誤消息),這意味着你**正在打破綁定,而不是你提供的代碼。 – cmannett85

相關問題