Reputation: 422
I'm having trouble figuring out where the user clicked in a nested wx.Menu.
I would like a method to retrive the client's name, if he's checked in or if he's checkout and how long he ins't allowed in. The client's themselves doens't have any unique ID to them. Should I do that?
I haven't done that yet because clients will be appended and removed from those sub-menus at runtime, so I just don't know how to keep that organized and coese in the code.
Thank you!
Edit: Here's my minimal example code:
As I said before, I would hope to get the client's name trought the menu label itself to identify them. But if that's not possible, let's give them a unique ID. Mind that I will be removing and adding clients to those menus at runtime (don't know how to do that yet. It seems pretty simple).
import wx
class ID:
PUT_BACK = 1000
WAIT_8 = 1001
WAIT_16 = 1002
WAIT_24 = 1003
CHECK_IN = 1004
CHECK_OUT = 1005
class Frame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
menu = wx.MenuBar()
lobby = wx.Menu()
check_in = wx.Menu()
check_out = wx.Menu()
wait_time = wx.Menu()
wait_time.Append(ID.PUT_BACK, 'and put back in the queue')
wait_time.Append(ID.WAIT_8, "and don't allow in for 8 hours")
wait_time.Append(ID.WAIT_16, "and don't allow in for 16 hours")
wait_time.Append(ID.WAIT_24, "and don't allow in for 24 hours")
queue = ['George', 'Vanessa', 'Erick']
for client in queue:
_in = check_in.Append(ID.CHECK_IN, client)
self.Bind(wx.EVT_MENU, self.OnCheckIn, _in)
_out = check_out.AppendSubMenu(wait_time, client)
self.Bind(wx.EVT_MENU, self.OnCheckOut, _out)
lobby.AppendSubMenu(check_in, 'Check in...' )
lobby.AppendSubMenu(check_out, 'Check out...')
menu.Append(lobby, 'Lobby')
self.SetMenuBar(menu)
def OnCheckIn(self, event):
obj = event.GetEventObject()
print('On Check in...')
def OnCheckOut(self, event):
obj = event.GetEventObject()
print(f'On Check out...')
app = wx.App()
frame = Frame(None).Show()
app.MainLoop()
Upvotes: 0
Views: 124
Reputation: 22443
You are making life difficult for yourself, taking the menu route. You may be better off choosing something like a wx.Treectrl
.
With that caveat out of the way, menus rely on an Id
reference but the menu itself and therefore sub-menus, don't have a user assigned Id, just the menu items within the menu.
That reference id must be unique.
This can make life tricky, if you need to carry some external reference forward through the menus, down into sub-menus, like a client reference, in this case.
You can create a dict
, as complicated as required, and store the menu id's as you go. Then use that dictionary to retrieve information, based on those item id's, which are passed in the subsequent events.
It probably sounds more complicated than it is.
For example:
import wx
Actions = ["Check In", "Put Back", "Wait 8", "Wait 16", "Wait 24"]
class Frame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent)
self.SetTitle(title)
self.CreateStatusBar()
menu = wx.MenuBar()
lobby = wx.Menu()
check_in = wx.Menu()
check_out = wx.Menu()
# create dictionary of clients to store reference id's
self.queue = {'George':[], 'Vanessa':[], 'Erick':[]}
for client in self.queue:
id = wx.NewIdRef()
self.queue[client].append(id.Value)
_in = check_in.Append(id, client, client)
self.Bind(wx.EVT_MENU, self.OnCheckIn, _in)
PUT_BACK = wx.NewIdRef()
WAIT_8 = wx.NewIdRef()
WAIT_16 = wx.NewIdRef()
WAIT_24 = wx.NewIdRef()
self.queue[client].extend((PUT_BACK.Value,WAIT_8.Value,WAIT_16.Value,WAIT_24.Value))
wait_time = wx.Menu()
wait_time.Append(PUT_BACK, "and put back in the queue", client+" Back")
wait_time.Append(WAIT_8, "and don't allow in for 8 hours", client+" +8")
wait_time.Append(WAIT_16, "and don't allow in for 16 hours", client+" +16")
wait_time.Append(WAIT_24, "and don't allow in for 24 hours", client+" +24")
self.Bind(wx.EVT_MENU, self.OnCheckOut, id=PUT_BACK)
self.Bind(wx.EVT_MENU, self.OnCheckOut, id=WAIT_8)
self.Bind(wx.EVT_MENU, self.OnCheckOut, id=WAIT_16)
self.Bind(wx.EVT_MENU, self.OnCheckOut, id=WAIT_24)
_out = check_out.AppendSubMenu(wait_time, client, client)
lobby.AppendSubMenu(check_in, 'Check in...' )
lobby.AppendSubMenu(check_out, 'Check out...')
menu.Append(lobby, 'Lobby')
self.SetMenuBar(menu)
def OnCheckIn(self, event):
id = event.GetId()
# quiz the dictionary for the Client based on unique reference id's
client = [c for c in self.queue if id in self.queue[c]]
print('Check in...', client[0])
def OnCheckOut(self, event):
id = event.GetId()
# quiz the dictionary for the Client based on unique reference id's
client = [c for c in self.queue if id in self.queue[c]]
# quiz the client entry for the action based on position (index)
index = self.queue[client[0]].index(id)
print(f'Check out..', client[0], "Action:",Actions[index])
app = wx.App()
frame = Frame(None, title="Check In/Out").Show()
app.MainLoop()
Upvotes: 1