【发布时间】:2013-07-06 08:24:26
【问题描述】:
Kivy 语言会自动在属性中创建内部绑定。例如,如果我们将 parent 的位置分配给 child 的位置,那么 child 的位置将自动更新:
Widget:
Label:
pos: self.parent.pos
在这种情况下,如果我们移动父Widget,那么子也将移动。如何解除属性pos与孩子的绑定?我知道如何解除绑定(属性)[http://kivy.org/docs/api-kivy.uix.widget.html#using-properties] 我绑定自己,但如果我不知道如何解除绑定它所绑定的方法的名称。
这是一个小例子来说明我的意思。 Button 向上 将GridLayout 移动到顶部,将Down 移动到底部。 Button Center 位于屏幕中间。我的问题是,当我单击 Up 或 Down 时,我的居中按钮不再存在。
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Example>:
GridLayout:
id: _box
cols: 3
size_hint: .7, .3
pos_hint: {'center_x': .5}
x: 0
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _box.y = 0
text: "Down"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: self.center_y = root.height/2
text: "Out of the Grid"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _box.top = root.height
text: "Up"
""")
class Example(FloatLayout):
pass
class ExampleApp(App):
def build(self):
return Example()
if __name__ == "__main__":
ExampleApp().run()
我为什么要这样做?我在GridLayout 上使用了一个不断更新位置的动画。按钮的正常位置应该在网格布局内,但有时其中一个按钮会飞过屏幕并返回到相同的位置。问题是,当我的网格布局也在移动时,我无法让它们飞行,因为属性已绑定,并且一旦按钮尝试飞行,它就会返回网格。这也意味着有时需要绑定。我想要的是控制绑定和解除绑定。
【问题讨论】:
-
为什么不只是从父级中删除小部件,将其添加到浮动布局中,然后在动画完成时使用 parent.add_widget(widget, index) 将其重新添加回原来的位置。 Gridlayout 和类似布局的重点是控制它的孩子的位置。如果您不希望这样,只需从布局中删除小部件即可。
-
谢谢。最初,我正在做类似的事情。我的问题是 GridLayout 重新组织了小部件。所以,我添加了另一个级别,在我的示例中,按钮级别没有附加到任何
Layout(只是一个普通的Widget)。它不起作用,因为pos: self.parent.pos仍在绑定Button和Widgetpos。我用 Python 结束了绑定和解除绑定,所以我现在有了控制权。 -
等等,你是不是建议通过将
Button添加到FloatLayout,然后它会将事物重新绑定到新的父级?我会尝试,但我知道我不这么认为。 @Tshirman 之前向我解释过,此绑定是由构建器完成的,因为我有 reverse issue with a canvas。 -
@qua-non,尽管我不相信,但这确实有效。嗯,差不多。这很奇怪,但在我按下
Up或Down按钮之前,按钮不会进入垂直中间。在执行其他操作之前,它不会立即更新。然而,当我把它放回网格时它工作得很好。换句话说,当我从盒子中取出时它不会立即起作用,但当我把它放回去时它会起作用。我会粘贴代码作为答案。