Kivy:在更新功能中操纵动态创建的小部件 [英] Kivy: Manipulating dynamically created widgets in update function

查看:132
本文介绍了Kivy:在更新功能中操纵动态创建的小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在此处的答案中扩展代码由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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆