我正在编写一个程序,右侧有一个按钮面板,可以根据用户输入/操作成功地将方法绑定到每个按钮。我的问题是我不能明确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()
属性的按钮。
如何列出对象的所有绑定方法,然后取消绑定它们?
答案 0 :(得分:3)
这是一个玩具示例,演示设置,保存和稍后清除回调。当按下a_button
或b_button
时,会触发set_callbacks
,这会将回调绑定到所有MyButton
。 MyButton
有一个列表属性_cb
,用于存储用户定义的回调。 c_button
将触发clear_callbacks
,MyButton
会遍历每个_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()