2016-02-10 61 views
3

我正在編寫一個程序,該程序在右側有一個按鈕面板,可以根據用戶輸入/操作成功地將方法綁定到每個方法。我的問題是,我不能明確地方法unbind(),因爲方法綁定是動態的。Kivy - 解除綁定到按鈕上的所有方法

考慮;

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 

證明我有一個綁定weakmethods的增加列表,每次調用該方法,但解除綁定功能不解除綁定的方法。

儘管我的代碼示例沒有顯示它,但綁定的方法會定期更改,而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

我打算建議使用'fbind' /'unbind'。你可以顯示你的'fbind'的用法嗎?請注意,語法略有不同。 – zeeMonkeez

+0

我偶然發現了這一點,但顯然「Button」沒有屬性'fbind'... ...? - 是的,1時刻 – Chazara

+0

'ref.fbind('on_release',self.SignPopupMethod,str(signText))'是我如何使用它 – Chazara

回答

3

這是玩具示例,演示設置,保存以及稍後清除回調。當a_buttonb_button被按下時,set_callbacks被觸發,它將回調綁定到所有的MyButtons。 MyButton有一個列表屬性_cb存儲用戶定義的回調。 c_button將觸發clear_callbacks,它會經歷MyButton_cb列表中的每個列表,並取消綁定每個存儲的回調。

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

kv_str = """ 
<[email protected]>: 
    _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() 
+0

謝謝你的時間和精力zee!我將在明天晚上實施我的更改並回報:) – Chazara

+0

使用按鈕上的列表屬性來存儲部分內容,並稍後從列表中刪除項目,這是天才!它工作完美無瑕。需要注意的是,我仍然在按鈕'AttributeError:'Button'對象上有'fbind'和'unbind'問題,儘管列表的方法學也使用了'bind'和'unbind',但它們沒有屬性'fbind' !再次感謝你。 – Chazara

+0

有一點需要注意:即使使用bind,它們也可以多次綁定(如本例所示)。需要更多邏輯來防止... – zeeMonkeez