【问题标题】:Kivy - Binding a button in a popupKivy - 在弹出窗口中绑定一个按钮
【发布时间】:2016-08-23 19:13:44
【问题描述】:

我目前正在 Kivy 中制作一个简单的应用程序,其中包含一个包含自定义小部件的 Popup 对象。我希望能够从主屏幕访问小部件(按钮按下等)的信息,但我遇到了按钮未实例化的问题。

下面给出了一个(大部分)最小(部分)工作示例。

import kivy
kivy.require('1.9.1')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.checkbox import CheckBox
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
from kivy.lang import Builder

Builder.load_string('''
<Main>
    popup: popup
    BoxLayout:
        id: boxlayout
        Button:
            text: "Open Popup"
            on_release: popup.open(); root.create_popup()
        Popup:
            id: popup
            title: "Example popup"
            on_parent: if self.parent == boxlayout: boxlayout.remove_widget(self)
            PopupContent:

<PopupContent>:
    closer: closer
    # Suppose there is a more complicated nested layout structure here
    BoxLayout:
        orientation: 'vertical'
        CheckBox:
        Button:
            id: closer
            text: "Close popup"
''')


class PopupContent(BoxLayout):

    def __init__(self,**kwargs):
        super(PopupContent, self).__init__(**kwargs)


class Main(BoxLayout):

    popup = ObjectProperty()

    def __init__(self,**kwargs):
        super(Main, self).__init__(**kwargs)

    # Callback from button in PopupContent
    def closer_callback(self,*args):
        print("callback called!")
        self.popup.dismiss()

    # Creates container widget for popup and binds button to perform callback
    def create_popup(self,*args):
        popup_content = PopupContent()
        popup_content.closer.bind(on_release = self.closer_callback)

        # Problem: This returns "<type 'kivy.weakproxy.WeakProxy'>"
        print(type(popup_content.closer))


class TestApp(App):

    def build(self):
        return Main()

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

正如我在代码中注释的那样,我尝试绑定 PopupContent 小部件中的按钮,以便在按下时在我的主屏幕中运行一个方法,但该按钮尚未创建,因此没有进行此类绑定。

我怎样才能绑定这个按钮?

【问题讨论】:

    标签: python-2.7 kivy


    【解决方案1】:

    原来我在创建示例时犯了一个错误 - 尽管我创建了 PopupContent 小部件的一个实例,但我从未将它添加到 Popup 小部件中。修复它,它现在可以正常工作了。

    import kivy
    kivy.require('1.9.1')
    
    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.popup import Popup
    from kivy.uix.checkbox import CheckBox
    from kivy.uix.button import Button
    from kivy.properties import ObjectProperty
    from kivy.lang import Builder
    
    Builder.load_string('''
    <Main>
        popup: popup
        BoxLayout:
            id: boxlayout
            Button:
                text: "Open Popup"
                on_release: popup.open(); root.create_popup()
            Popup:
                id: popup
                title: "Example popup"
                on_parent: if self.parent == boxlayout: boxlayout.remove_widget(self)
    
    <PopupContent>:
        closer: closer
        # Suppose there is a more complicated nested layout structure here
        BoxLayout:
            orientation: 'vertical'
            CheckBox:
            Button:
                id: closer
                text: "Close popup"
    ''')
    
    
    class PopupContent(BoxLayout):
    
        def __init__(self,**kwargs):
            super(PopupContent, self).__init__(**kwargs)
    
    
    class Main(BoxLayout):
    
        popup = ObjectProperty()
    
        def __init__(self,**kwargs):
            super(Main, self).__init__(**kwargs)
    
        # Callback from button in PopupContent
        def closer_callback(self,*args):
            print("callback called!")
            self.popup.dismiss()
    
        # Creates container widget for popup and binds button to perform callback
        def create_popup(self,*args):
            popup_content = PopupContent()
            self.popup.content = popup_content
            popup_content.closer.bind(on_release = self.closer_callback)
    
            # Note: This still returns "<type 'kivy.weakproxy.WeakProxy'>"
            #       But the button is correctly bound regardless
            print(type(popup_content.closer))
    
    
    class TestApp(App):
    
        def build(self):
            return Main()
    
    if __name__ == '__main__':
        TestApp().run()
    

    我的理解是,当第一次创建 PopupContent 实例时,出于性能原因,实际小部件在显示之前不会加载(可能是通过某些加载函数)。然而,在那之前,我们仍然通过 WeakProxy 获得“弱引用”,这使得绑定成为可能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多