2015-08-14 57 views
1

在我的程序中,我有一個具有插入子菜單的上下文菜單。我不想爲子菜單中的每個選項創建不同的功能,而是希望將所有選項綁定到相同的功能。有沒有辦法讓我確定所選項目的標籤或ID,以便我可以將其傳遞給不同的功能?如何在wxPython中獲取選定的菜單項?

編輯:經過一些研究,我發現函數GetId(),這是我想要的,但我仍然需要從ID獲得標籤。我可能能夠使用FindWindowById,它是wx.Window的一個函數,但它只能查看窗口的子項。該框架似乎不是子菜單中項目的父項,所以我不能僅僅執行frame.FindWindowById(id)

回答

1

使用部分發送一個選項(一些唯一的ID)到一個共同的功能。如果您有很多菜單項,請使用for()循環,將返回值存儲在列表中(而不是menu_item_x),然後遞增計數器以發送到函數。

import wx 
from functools import partial 

class MenuCallback(object): 

    def __init__(self, parent, id): 
     self.frame=wx.Frame(None) 
     menu_bar = wx.MenuBar() 
     menu1 = wx.Menu() 
     menu_item_1 = menu1.Append(-1, "&Option #1") 
     menu_item_2 = menu1.Append(-1, "&Option #2") 
     menu_item_3 = menu1.Append(-1, "&Exit...") 

     menu_bar.Append(menu1, "&File") 
     self.frame.SetMenuBar(menu_bar) 
     self.frame.Bind(wx.EVT_MENU, partial(self.option_chosen, 1), 
         menu_item_1) 
     self.frame.Bind(wx.EVT_MENU, partial(self.option_chosen, 2), 
         menu_item_2) 
     self.frame.Bind(wx.EVT_MENU, self.on_close, menu_item_3) 

     self.frame.Show(True) 

    def option_chosen(self, number, event): 
     print "option chosen =", number 

    def on_close(self, event): 
     self.frame.Close(True) 

app = wx.PySimpleApp() 
MC=MenuCallback(parent=None, id=-1) 
app.MainLoop() 
+1

只是一個'wx.PySimpleApp'已被棄用的FYI。我不認爲它會在wxPython Phoenix中可用。 –

0

它可能不是很漂亮,但我覺得使用菜單Id範圍的列表是有效的。它不僅是容易理解的,但它也很靈活,就像這樣:

進口WX

類MenuCallback(wx.Frame):

def __init__(self, *args, **kwds): 
    self.frame=wx.Frame.__init__(self, *args, **kwds) 
    self.menubar = wx.MenuBar() 
    menu1 = wx.Menu() 
    menu_item_1 = menu1.Append(wx.ID_OPEN, "&File") 
    menu_item_2 = menu1.Append(wx.ID_EXIT, "&Exit...") 
#Build a list of things via another function or just a declaration 
    self.list_of_things = ["Thing No 1", "Thing No 2", "Thing No 3"] 
    list_used = wx.Menu() 
    thing_count = 101 

    for thing in self.list_of_things: 
     t1 = wx.MenuItem(list_used, thing_count, thing) 
     list_used.AppendItem(t1) 
     thing_count +=1 

    thing_end = wx.MenuItem(list_used,199,'End of List') 
    list_used.AppendItem(thing_end) 

    menu1.AppendMenu(wx.ID_FILE,'&Things',list_used) 
    self.menubar.Append(menu1, "&File") 
    self.SetMenuBar(self.menubar) 
# Create bindings for the Thing list 
    i_count = 101 
    for i in self.list_of_things: 
     self.Bind(wx.EVT_MENU, self.OnThingOpen, id=i_count) 
     i_count = i_count + 1 
    self.Bind(wx.EVT_MENU, self.OnThingEnd, id=199) 
    self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) 
    self.Show(True) 

def OnThingOpen(self, event): 
    id_index = 101 
    id_selected = event.GetId() 
    id_selected = id_selected - id_index 
    print "Option =", id_selected 
    print "Thing selected =", str(self.list_of_things[id_selected]) 

def OnThingEnd(self, event): 
    id_selected = event.GetId() 
    print "Option =", id_selected 

def OnClose(self, event): 
    self.Close() 

if __name__ == '__main__': 
    app = wx.App() 
    MC=MenuCallback(parent=None, id=-1) 
    app.MainLoop() 
2

已經提供了一個解決你的問題,我意識到應該有另一種實現我的解決方案的方式。事實上,我可以自己採用這種方式,因爲它更清潔,記憶力更少。這使用event.GetEventObject()方法。

import wx 

class MenuCallback(wx.Frame): 

    def __init__(self, *args, **kwds): 
     self.frame=wx.Frame.__init__(self, *args, **kwds) 
     self.menubar = wx.MenuBar() 
#  self.statusbar = wx.StatusBar(self-1) 
     self.CreateStatusBar() 
     self.SetStatusText("Demonstration of wxPython") 
     menu1 = wx.Menu() 
     menu_item_1 = menu1.Append(wx.ID_OPEN, "&File") 
     menu_item_2 = menu1.Append(wx.ID_EXIT, "&Exit...") 
    #Build a list of things via another function or just a declaration 
     self.list_of_things = ["Thing No 1", "Thing No 2", "Thing No 3"] 
     list_used = wx.Menu() 
     thing_count = 101 

     for thing in self.list_of_things: 
      t1 = wx.MenuItem(list_used, thing_count, thing) 
      list_used.AppendItem(t1) 
      thing_count +=1 

     thing_end = wx.MenuItem(list_used,199,'End of List') 
     list_used.AppendItem(thing_end) 

     menu1.AppendMenu(wx.ID_FILE,'&Things',list_used) 
     menu1.SetHelpString(wx.ID_FILE, 'Select from the list of things') 

     self.menubar.Append(menu1, "&File") 
     self.SetMenuBar(self.menubar) 
    # Create bindings for the Thing list 
     i_count = 101 
     for i in self.list_of_things: 
      self.Bind(wx.EVT_MENU, self.OnThingOpen, id=i_count) 
      i_count = i_count + 1 
     self.Bind(wx.EVT_MENU, self.OnThingEnd, id=199) 
     self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) 
     self.Show(True) 

    def OnThingOpen(self, event): 
     id_selected = event.GetId() 
     obj = event.GetEventObject() 
     print "Option =", id_selected 
     print obj.GetLabel(id_selected) 
     print "From the range:" 
     for i in range(obj.MenuItemCount): 
      print "\t\t", obj.MenuItems[i].GetLabel() 

    def OnThingEnd(self, event): 
     pass 

    def OnClose(self, event): 
     self.Close() 

if __name__ == '__main__': 
    app = wx.App() 
    MC=MenuCallback(parent=None, id=-1) 
    app.MainLoop() 
相關問題