I've gotten confused at how to use the wxpopupmenu
when there are few possible sets of menu items that could
pop up. I want to:
1. set up a popup menu made from one of a few lists of
titles, with that list used depending on conditions in the app.
(because I will have a few different possible menus that
could pop up)
3. Bind the popup menu to an event handler which can be passed
the ID of the item selected in the popup.
4. From that ID, get the title of the menu item, and then do
things based on that title.
This seems like it should be easy, but I keep hitting a wall.
I'm trying to make a hybrid of the code in the wxPython demo
and an older one on the wiki found here:
http://wiki.wxpython.org/PopupMenuOnRightClick
...but because it is using unordered dictionaries I have a
problem: the menu the items are in a random order (which
I don't want). Below is a runnable sample that shows this.
Click on either of the colored panels multiple times and you'll
get inconsistent orderings of the titles.
I'd use just a list to build the popup menu, but then I would
have no mapping between the title and its ID for use in the
event handler. I need the event handler to know which of
the titles was the one clicked on. So right now I feel stuck
with either a consistently ordered popup menu that has a
useless event handler, or one that does but whose titles
are randomly ordered. What am I doing wrong?
Thank you, and code below...
···
#-----------------------------------------------------------------------------
#Boa:Frame:Frame1
import wx
def create(parent):
return Frame1(parent)
[wxID_FRAME1, wxID_FRAME1PANEL1, wxID_FRAME1PANEL2, wxID_FRAME1PANEL3,
] = [wx.NewId() for _init_ctrls in range(4)]
class Frame1(wx.Frame):
def _init_ctrls(self, prnt):
# generated method, don't edit
wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
pos=wx.Point(177, 196), size=wx.Size(437, 245),
style=wx.DEFAULT_FRAME_STYLE, title='Frame1')
self.SetClientSize(wx.Size(429, 211))
self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self,
pos=wx.Point(0, 0), size=wx.Size(429, 211),
style=wx.TAB_TRAVERSAL)
self.panel2 = wx.Panel(id=wxID_FRAME1PANEL2, name='panel2',
parent=self.panel1, pos=wx.Point(24, 24), size=wx.Size(184, 160),
style=wx.TAB_TRAVERSAL)
self.panel2.SetBackgroundColour(wx.Colour(0, 128, 255))
self.panel2.Bind(wx.EVT_RIGHT_DOWN, self.OnPanel2RightDown)
self.panel3 = wx.Panel(id=wxID_FRAME1PANEL3, name='panel3',
parent=self.panel1, pos=wx.Point(216, 24), size=wx.Size(192, 160),
style=wx.TAB_TRAVERSAL)
self.panel3.SetBackgroundColour(wx.Colour(0, 128, 128))
self.panel3.Bind(wx.EVT_RIGHT_DOWN, self.OnPanel3RightDown)
def __init__(self, parent):
self._init_ctrls(parent)
def OnPanel2RightDown(self, event):
self.menu_titles = ["one", "two", "three"]
self.mypopupmenu()
def OnPanel3RightDown(self, event):
self.menu_titles = ["four", "five", "six"]
self.mypopupmenu()
def mypopupmenu(self):
menu = wx.Menu()
#A dict to access menu titles by ID--will be used in event handler
self.menu_title_by_id = {}
for title in self.menu_titles:
self.menu_title_by_id[ wx.NewId() ] = title
#make the menu
for (popID,title) in self.menu_title_by_id.items():
item = wx.MenuItem(menu, popID, title)
menu.AppendItem(item)
#bind to a single event handler
self.Bind(wx.EVT_MENU, self.OnPopupMenu, item)
self.PopupMenu( menu)
def OnPopupMenu(self,event):
title = self.menu_title_by_id[ event.GetId() ]
print title
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = create(None)
frame.Show()
app.MainLoop()