【问题标题】:Kivy - Dispatching custom events to child widgetsKivy - 将自定义事件分派给子部件
【发布时间】:2023-02-10 09:19:29
【问题描述】:

我想将事件从 LayoutDemoApp 分派给子小部件。目标是让 websocket 侦听器调度事件,允许任何小部件侦听它们(例如更新标签等)。我可能误解了这里的事件是如何工作的以及 Kivy 的例子。 register_event_type 只是LayoutDemoApp 对象的本地对象,这是不可能的吗?

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class MyButton(Button):
    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)
        
        self.bind(on_foo=self.on_foo)

    def on_foo(self, *args, **kwargs):
        print("MyButton.on_foo")


class LayoutDemoApp(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.register_event_type("on_foo")

    def build(self):
        root = BoxLayout(orientation='vertical')
        r1 = BoxLayout()
        
        button12 = MyButton(text='B1')
        button12.bind(on_press=self.on_bar)

        r1.add_widget(button12)
        root.add_widget(r1)
        return root

    def on_bar(self, *args, **kwargs):
        print("LayoutDemoApp.on_bar")
        self.dispatch("on_foo")
    
    def on_foo(self, *args, **kwargs):
        pass

if __name__ == '__main__':
    LayoutDemoApp().run()

【问题讨论】:

  • 如果 on_foo 是属于 MyButton 的事件,则必须使用默认处理程序在那里注册。

标签: python kivy


【解决方案1】:

在根布局上调用 dispatch_children 方法而不是应用程序本身,并按照 @ApuCoder 的建议在目标小部件中注册事件应该会给出所需的结果。

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button


class MyButton(Button):
    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)
        self.register_event_type("on_foo")

    def on_foo(self, *args, **kwargs):
        (caller,) = args
        print(f"{self.text}'s on_foo called by {caller}")


class LayoutDemoApp(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self):
        root = BoxLayout(orientation="vertical")
        r1 = BoxLayout()

        button1 = MyButton(text="B1")
        button1.bind(on_press=self.on_bar)
        button2 = MyButton(text="B2")
        button2.bind(on_press=self.on_bar)

        r1.add_widget(button1)
        r1.add_widget(button2)
        root.add_widget(r1)
        return root

    def on_bar(self, instance):
        print("LayoutDemoApp.on_bar")
        self.root.dispatch_children("on_foo", instance.text)


if __name__ == "__main__":
    a = LayoutDemoApp().run()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    相关资源
    最近更新 更多