2009-06-10 42 views
4

在以下代碼中(靈感來自this片段),我使用單個事件處理程序buttonClick來更改窗口的標題。目前,我需要評估事件的ID是否與按鈕的ID相對應。如果我決定添加50個按鈕而不是2個,則此方法可能變得麻煩。有一個更好的方法嗎?獲取調用事件按鈕名稱的最佳方法?

import wx 

class MyFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, 'wxBitmapButton', 
      pos=(300, 150), size=(300, 350)) 
     self.panel1 = wx.Panel(self, -1) 

     self.button1 = wx.Button(self.panel1, id=-1, 
      pos=(10, 20), size = (20,20)) 
     self.button1.Bind(wx.EVT_BUTTON, self.buttonClick) 

     self.button2 = wx.Button(self.panel1, id=-1, 
      pos=(40, 20), size = (20,20)) 
     self.button2.Bind(wx.EVT_BUTTON, self.buttonClick) 

     self.Show(True) 

    def buttonClick(self,event): 
     if event.Id == self.button1.Id: 
      self.SetTitle("Button 1 clicked") 
     elif event.Id == self.button2.Id: 
      self.SetTitle("Button 2 clicked")    

application = wx.PySimpleApp() 
window = MyFrame() 
application.MainLoop() 

回答

9

你可以給該按鈕的名稱,然後看看事件處理程序的名稱。

當你使按鈕

b = wx.Button(self, 10, "Default Button", (20, 20)) 
b.myname = "default button" 
self.Bind(wx.EVT_BUTTON, self.OnClick, b) 

當點擊該按鈕:

def OnClick(self, event): 
    name = event.GetEventObject().myname 
+0

我經常上的小部件設置的屬性以及當我想不出更好的辦法。 – FogleBird 2009-06-11 23:01:04

3

保持一個dict是與作爲的按鈕和按鈕名稱或任何值的.Id鍵,所以不是很長if/elif連鎖你buttonClick做單dict查找。

代碼片段:在__init__,添加的創建和更新的dict的:

self.panel1 = wx.Panel(self, -1) 
self.thebuttons = dict() 

self.button1 = wx.Button(self.panel1, id=-1, 
    pos=(10, 20), size = (20,20)) 
self.thebuttons[self.button1.Id] = 'Button 1' 
self.button1.Bind(wx.EVT_BUTTON, self.buttonClick) 

等50個按鈕(或其他),他們可能在一個循環中得到更好的創建,順便說一句;-)] 。 所以buttonClick變爲:

def buttonClick(self,event): 
     button_name = self.thebuttons.get(event.Id, '?No button?') 
     self.setTitle(button_name + ' clicked') 
1

您可以創建按鈕的字典,並以此爲基礎進行的id一下......是這樣的:

class MyFrame(wx.Frame): 
    def _add_button (self, *args): 
     btn = wx.Button (*args) 
     btn.Bind (wx.EVT_BUTTON, self.buttonClick) 
     self.buttons[btn.id] = btn 
    def __init__ (self): 
     self.button = dict() 
     self._add_button (self.panel1, id=-1, 
     pos=(10, 20), size = (20,20)) 

    self._add_button = (self.panel1, id=-1, 
     pos=(40, 20), size = (20,20)) 

    self.Show (True) 

    def buttonClick(self,event): 
     self.SetTitle (self.buttons[event.Id].label) 
0

我遇到了類似的問題:我正在生成基於用戶提供的數據的按鈕,並且我需要這些按鈕來影響另一個班級,所以我需要傳遞關於buttonclick的信息。我所做的是明確地將按鈕ID分配給我生成的每個按鈕,然後將其存儲在字典中以供稍後查找。

我原以爲會有更漂亮的方法來做到這一點,構建一個傳遞更多信息的自定義事件,但我所見過的只是字典查找方法。另外,我還會保留一些按鈕的列表,以便在需要時刪除所有按鈕。

下面是類似的東西稍微擦洗代碼示例:

self.buttonDefs = {} 
self.buttons = [] 
id_increment = 800 
if (row, col) in self.items: 
    for ev in self.items[(row, col)]: 
     id_increment += 1 
     #### Populate a dict with the event information 
     self.buttonDefs[id_increment ] = (row, col, ev['user']) 
     #### 
     tempBtn = wx.Button(self.sidebar, id_increment , "Choose", 
          (0,50+len(self.buttons)*40), (50,20)) 
     self.sidebar.Bind(wx.EVT_BUTTON, self.OnShiftClick, tempBtn) 
     self.buttons.append(tempBtn) 

def OnShiftClick(self, evt): 
    ### Lookup the information from the dict 
    row, col, user = self.buttonDefs[evt.GetId()] 
    self.WriteToCell(row, col, user) 
    self.DrawShiftPicker(row, col) 
7

我建議你使用不同的事件處理程序來處理來自各個按鈕的事件。如果有很多共性的,你可以結合到這一個功能,返回你想要的特定行爲的功能,例如:

def goingTo(self, where): 
    def goingToHandler(event): 
     self.SetTitle("I'm going to " + where) 
    return goingToHandler 

def __init__(self): 
    buttonA.Bind(wx.EVT_BUTTON, self.goingTo("work")) 
    # clicking will say "I'm going to work" 
    buttonB.Bind(wx.EVT_BUTTON, self.goingTo("home")) 
    # clicking will say "I'm going to home" 
+0

哇,我認爲這是比字典查找方法更好的方法。這樣,當你可能只使用一個條目時,你不會填充「dict」。 – pbh101 2009-06-10 23:26:08

7

趁你可以像Python語言做什麼。您可以將額外的參數傳遞給您的事件回調函數,就像這樣。

import functools 

def __init__(self): 
    # ... 
    for i in range(10): 
     name = 'Button %d' % i 
     button = wx.Button(parent, -1, name) 
     func = functools.partial(self.on_button, name=name) 
     button.Bind(wx.EVT_BUTTON, func) 
    # ... 

def on_button(self, event, name): 
    print '%s clicked' % name 

當然,參數可以是任何你想要的。

+1

好的方法和使用酷的新Python功能(無論如何,2.5對我來說都是新的)。我經常會做這個'lambda'版本,雖然'functools.partail'當然更清晰,沒有麻煩的名稱綁定問題。 – tom10 2009-06-11 23:01:34

0

我需要做同樣的事情來跟蹤按鈕。我使用了一個lambda函數來綁定到事件。這樣我就可以將整個按鈕對象傳遞給事件處理函數來相應地進行操作。

class PlatGridderTop(wx.Frame): 
     numbuttons = 0 
     buttonlist = [] 


     def create_another_button(self, event): # wxGlade: PlateGridderTop.<event_handler> 
       buttoncreator_id = wx.ID_ANY 
       butonname = "button" + str(buttoncreator_id) 
       PlateGridderTop.numbuttons = PlateGridderTop.numbuttons + 1 
       thisbutton_number = PlateGridderTop.numbuttons 

       self.buttonname = wx.Button(self,buttoncreator_id ,"ChildButton %s" % thisbutton_number) 
       self.Bind(wx.EVT_BUTTON,lambda event, buttonpressed=self.buttonname: self.print_button_press(event,buttonpressed),self.buttonname) 
       self.buttonlist.append(self.buttonname) 
       self.__do_layout() 
       print "Clicked plate button %s" % butonname 
       event.Skip() 
     def print_button_press(self,event,clickerbutton): 
       """Just a dummy method that responds to a button press""" 
       print "Clicked a created button named %s with wxpython ID %s" % (clickerbutton.GetLabel(),event.GetId()) 

免責聲明:這是我的第一篇到計算器