Kivy:在更新功能中操纵动态创建的小部件 [英] Kivy: Manipulating dynamically created widgets in update function
问题描述
我正在尝试在此处的答案中扩展代码由Nykakin提供,其中小部件在Kivy中动态定义,动态分配ID,然后根据ID进行操作.
I am trying to extend the code in the answer here provided by Nykakin where widgets are defined on the fly in Kivy, dynamically assigned IDs, and then manipulated based on ID.
最终游戏"是通过根据ID更改小部件的位置来实现一些基本的2D物理.
The 'end game' is to implement some basic 2D physics by changing position of widgets based on ID.
我无法通过更新功能遍历"小部件树(内联错误).
I am not able to 'walk' the widget tree from the update function (errors inline).
有可能做这样的事情吗?
Is it possible to do such a thing?
这是代码:
#code begins here
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.factory import Factory
class MyWidget(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text="Print IDs", id="PrintIDsButton")
button.bind(on_release=self.print_label)
self.add_widget(button)
# crate some labels with defined IDs
for i in range(5):
self.add_widget(Button(text=str(i), id="button no: " + str(i)))
# update moved as per inclement's recommendation
Clock.schedule_interval(MyApp.update, 1 / 30.0)
def print_label(self, *args):
children = self.children[:]
while children:
child = children.pop()
print("{} -> {}".format(child, child.id))
# we can change label properties from here! Woo!
children.extend(child.children)
if child.id == "PrintIDsButton":
child.text = child.text + " :)"
class MyApp(App):
def build(self):
return MyWidget()
def update(self, *args):
#ERROR# AttributeError: 'float' object has no attribute 'root'
children = self.root.children[:]
#ERROR# TypeError: 'kivy.properties.ListProperty' object is not subscriptable
#children = MyWidget.children[:]
#while children:
# child = children.pop()
# print("{} -> {}".format(child, child.id))
# children.extend(child.children)
#ERROR# TypeError: 'kivy.properties.ListProperty' object is not iterable
#for child in MyWidget.children:
# print("{} -> {}".format(child, child.id))
if __name__ == '__main__':
MyApp().run()
- Windows 7 SP1
- Kivy 1.8.0/Python 3.3
我很抱歉,如果我的术语不正确! (并感谢您的宝贵时间)
My apologies if my terminology is incorrect! (and thank you for your time)
推荐答案
因此,将更新功能放在'MyWidget'类中,然后通过调用self.children来访问'MyWidget'中的元素!
So putting the update function within the 'MyWidget' class and then accessing elements within 'MyWidget' by calling self.children worked!
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.factory import Factory
class MyWidget(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text="Print IDs", id="PrintIDsButton")
button.bind(on_release=self.print_label)
self.add_widget(button)
# crate some labels with defined IDs
for i in range(5):
self.add_widget(Button(text=str(i), id="button no: " + str(i)))
# update moved as per inclement's recommendation
Clock.schedule_interval(self.update, 1 / 5.0)
def print_label(self, *args):
children = self.children[:]
while children:
child = children.pop()
print("{} -> {}".format(child, child.id))
# Add smiley by ID
children.extend(child.children)
if child.id == "PrintIDsButton":
child.text = child.text + " :)"
def update(self, *args):
children = self.children[:]
while children:
child = children.pop()
# remove smiley by ID
if child.id == "PrintIDsButton":
child.text = "Print IDs"
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
再次感谢您!
这篇关于Kivy:在更新功能中操纵动态创建的小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!