【问题标题】:Binding function to a button inside a Custom Widget from outside从外部将函数绑定到自定义小部件内的按钮
【发布时间】:2017-01-03 21:33:46
【问题描述】:

我制作了这个小部件:

<ImageButton>:
    source:''
    text:''
    release_fn: None
    Button:
        on_release: root.release_fn()
        size: root.size
        pos: root.pos
        BoxLayout:
            padding: 30
            size: self.parent.size
            pos: self.parent.pos
            orientation:'vertical'
            Image:
                id: img
                source: root.source
            Label:
                size_hint_y:.3
                text: root.text

现在我想将释放按钮时调用的函数传递给它,但我不知道该怎么做(我找不到任何答案...)

以下内容仅在最后一行给我一个语法错误(省略了 kivy 文件的其余部分和良好的工作部分)

ImageButton:
    source: 'iconUsuario.png'
    text: 'Usuario'
    release_fn: print('HI!')


     print('HI!')
         ^
 SyntaxError: invalid syntax

【问题讨论】:

    标签: kivy custom-widgets event-binding


    【解决方案1】:

    出于某种原因,Python 不喜欢使用它的 print 作为名称。尝试运行:

    def print():
        pass
    def print:
        pass
    

    在 print 上始终是 SyntaxError。 KV lang 基本上是这样做的:

    eval(print('bla'))
    

    所以,让我们有一个打印的包装。无论如何,您可能不会使用纯打印。然后你可能会注意到该函数返回None,那是因为它被调用时使用on_release: root.release_fn() 作为第一个值release_fn: something() 就像一个部分(当你调用partial(func, arg)() 时,函数确实被调用了)。

    这就是为什么你需要导入functools.partial,再做一次,以便在按下按钮后在所需位置调用该函数,而不是立即调用:

    on_release: root.release_fn()
    

    示例:

    from kivy.app import App
    from kivy.lang import Builder
    
    kv = """
    #:import partial functools.partial
    ImageButton:
        release_fn: partial(app.prints, 'bla')
    
    <ImageButton@ButtonBehavior+Image>:
        source:''
        text:''
        release_fn: None
        Button:
            on_release: root.release_fn()
            size: root.size
            pos: root.pos
            BoxLayout:
                padding: 30
                size: self.parent.size
                pos: self.parent.pos
                orientation:'vertical'
                Image:
                    id: img
                    source: root.source
                Label:
                    size_hint_y:.3
                    text: root.text
    """
    
    
    class TestApp(App):
        def prints(self, value):
            print(value)
    
        def build(self):
            return Builder.load_string(kv)
    
    
    if __name__ == '__main__':
        TestApp().run()
    

    【讨论】:

    • 感谢@KeyWeeUsr 的回答。我不知道部分,我会研究它。正如你所说, kv 真的得到了它的属性的评估。我只是回答了我自己的问题。我缺乏自定义事件。这是本案的最佳选择。无论如何,再次感谢:)
    【解决方案2】:

    好吧,事实证明这似乎不是最好的主意,我使用了自定义事件:

    class ImageButton(Widget):
        def __init__(self,*args,**kwargs):
            super(ImageButton,self).__init__(*args,**kwargs)
            self.register_event_type('on_release')
    
        def on_release(self,*args):
            pass
    
        def callback(self,instance):
            self.dispatch('on_release')
            pass
    

    kv 文件:

    <ImageButton>:
        source:''
        text:''
        Button:
            on_release: root.callback(self)
            size: root.size
            pos: root.pos
            BoxLayout:
                padding: 30
                size: self.parent.size
                pos: self.parent.pos
                orientation:'vertical'
                Image:
                    id: img
                    source: root.source
                Label:
                    size_hint_y:.3
                    text: root.text
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      相关资源
      最近更新 更多