Kivy - 取消绑定按钮上的所有方法

时间:2016-02-10 23:49:48

标签: python events bind kivy unbind

我正在编写一个程序,右侧有一个按钮面板,可以根据用户输入/操作成功地将方法绑定到每个按钮。我的问题是我不能明确unbind()方法,因为方法绑定是动态的。

考虑;

    i = 1
    while i <= 8:
        string = "action" + str(i) 
        #Buttons named 'action1, action1, ..., action8'
        ref = self.ids[string] 
        ref.text = ""
        observers = ref.get_property_observers('on_release')
        print observers
        ref.unbind()
        ref.bind(on_release=partial(self.BlankMethod, arg1))
        i += 1

线条;

        observers = ref.get_property_observers('on_release')
        print observers

每次调用方法时,显示我有一个增加的弱方法列表,但unbind函数不解除该方法的绑定。

虽然我的代码示例没有显示它,但绑定方法会定期更改,self.BlankMethod意味着覆盖原始绑定。事实并非如此,Button的约束方法也在增加。

[<kivy.weakmethod.WeakMethod object at 0x7f8cc826a810>] [<kivy.weakmethod.WeakMethod object at 0x7f8cc826a850>, <kivy.weakmethod.WeakMethod object at 0x7f8cc826acd0>]

我试过了;

        observers = ref.get_property_observers('on_release')
        if observers != []:
            for observer in observers:
                ref.unbind(observer)
        ref.bind(on_release=partial(self.Blank))

但是我回复了错误;

TypeError: unbind() takes exactly 0 positional arguments (1 given)

我看过使用funbind()函数,但后来给出了;

AttributeError: 'Button' object has no attribute 'funbind'

尝试在fbind()之前使用funbind()也会产生相同的错误,但是对于没有fbind()属性的按钮。

如何列出对象的所有绑定方法,然后取消绑定它们?

1 个答案:

答案 0 :(得分:3)

这是一个玩具示例,演示设置,保存和稍后清除回调。当按下a_buttonb_button时,会触发set_callbacks,这会将回调绑定到所有MyButtonMyButton有一个列表属性_cb,用于存储用户定义的回调。 c_button将触发clear_callbacksMyButton会遍历每个_cb的{​​{1}}列表,并取消绑定每个存储的回调。

from kivy.app import App
from kivy.lang import Builder
from functools import partial

kv_str = """
<MyButton@Button>:
    _cb: []
    my_id: 1
    text: "hello {}".format(self.my_id)
BoxLayout:
    orientation: 'vertical'
    BoxLayout:
        Button:
            id: a_button
            text: "a button"
        Button:
            id: b_button
            text: "b button"
        Button:
            id: c_button
            text: "clear callbacks"
    GridLayout:
        cols: 4
        id: grid
        MyButton:
            my_id: 1
        MyButton:
            my_id: 2
        MyButton:
            my_id: 3
        MyButton:
            my_id: 4
"""

def cb(sender, arg='nothing'):
    print "we got: {} pressed with {}".format(sender.text, arg)

class MyApp(App):
    def build(self):
        root = Builder.load_string(kv_str)

        def set_callbacks(sender):
            for b in root.ids.grid.children:
                new_cb = partial(cb, arg=sender.text)
                b._cb.append(new_cb)
                b.fbind('on_press', new_cb)
        def clear_callbacks(sender):
            for b in root.ids.grid.children:
                for cb in b._cb:
                    b.funbind('on_press', cb)
                b._cb = []
        root.ids.a_button.bind(on_press=set_callbacks)
        root.ids.b_button.bind(on_press=set_callbacks)
        root.ids.c_button.bind(on_press=clear_callbacks)
        return root

if __name__ == '__main__':
    a = MyApp()
    a.run()