2015-05-06 45 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

相关问题