从外部将功能绑定到Custom Widget内的按钮

时间:2017-01-03 21:33:47

标签: kivy custom-widgets event-binding

我做了这个小工具:

<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

2 个答案:

答案 0 :(得分:0)

Python并不喜欢出于某种原因将其打印用作其他任何名称。试着运行:

def print():
    pass
def print:
    pass

总是SyntaxError t 。 KV郎基本上是这样做的:

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()

答案 1 :(得分:0)

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

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