[wxPython] dynamically generated menu items

Hello, I want to make dynamically generated menu.
(i.e. the text and the size of menu items are variable.)
I used same ID on each menu item generated,
because I want to handle its event as same manner in same handler function.
But, i don't know how to distingush which item is clicked
in the handler function.
How can I associate any piece of data with each menu item
like wxTreeItemData of wxTreeCtrl?

Hello, I want to make dynamically generated menu.
(i.e. the text and the size of menu items are variable.)
I used same ID on each menu item generated,
because I want to handle its event as same manner in same handler

function.

But, i don't know how to distingush which item is clicked
in the handler function.

Why not give them distinct ID's and have an EVT_MENU for each that points
to the same function? Then you can use a dictionary to dispatch the
correct function for each item.

Something along these lines:

class SomeClass(wxSomeBaseClass):
    ...
    self.dispatchTable = {}
    menuItems = [ # this could be created from a file or something
        ("Some item", someFunction),
        ("Another item", anotherFunction),
    ]
    menu = wxMenu()
    for label, function in menuItems:
        id = wxNewId()
        menu.Append(id, label)
        EVT_MENU(self, id, function)
    ...

    def someMethod(self, event):
        # do some stuff
        ...
        self.dispatchTable[event.GetId()]()

How can I associate any piece of data with each menu item
like wxTreeItemData of wxTreeCtrl?

I don't think you can.

···

On Fri, 29 Mar 2002 00:35:32 +0900 June-young Jang wrote:

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 x308 (800) 735-0555 x308

Oops. Got ahead of myself. Example should be:

class SomeClass(wxSomeBaseClass):
    ...
    self.dispatchTable = {}
    menuItems = [ # this could be created from a file or something
        ("Some item", someFunction),
        ("Another item", anotherFunction),
    ]
    menu = wxMenu()
    for label, function in menuItems:
        id = wxNewId()
        menu.Append(id, label)
        EVT_MENU(self, id, self.someMethod)
        self.dispatchTable[id] = function
    ...

    def someMethod(self, event):
        # do some stuff
        ...
        self.dispatchTable[event.GetId()]()

···

On Thu, 28 Mar 2002 13:54:06 -0800 Cliff Wells wrote:

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 x308 (800) 735-0555 x308

Cliff Wells wrote:

Oops. Got ahead of myself. Example should be:

class SomeClass(wxSomeBaseClass):
    ...
    self.dispatchTable = {}
    menuItems = [ # this could be created from a file or something
        ("Some item", someFunction),
        ("Another item", anotherFunction),
    ]
    menu = wxMenu()
    for label, function in menuItems:
        id = wxNewId()
        menu.Append(id, label)
        EVT_MENU(self, id, self.someMethod)
        self.dispatchTable[id] = function

    ...

    def someMethod(self, event):
        # do some stuff
        ...
        self.dispatchTable[event.GetId()]()

Of course, this begs the question of why not simply use:

    for label, function in menuitems:
        id = wxNewId()
        menu.Append(id, label)
        EVT_MENU(self, id, function)

and let wxWindows do the dispatching *for* you, since that's what it's
designed for... :wink: On the other hand, if the point is to run the same
function with a different parameter for each menu item, then your
proposal would be ideal, substituting a dictionary of the desired
parameters for your dictionary of functions.

Jeff Shannon
Technician/Programmer
Credit International

···

On Thu, 28 Mar 2002 13:54:06 -0800 > Cliff Wells wrote:

This is what I assumed the OP wanted (although _why_ I don't know :wink:

I can see something like this used if say, the programmer wanted to modify
the menu after the user clicks on an item (maybe the menu contains a list
of recently-opened files and the most recent should be moved to the top of
the list). The common menu event handling function could modify the menu
and then call the appropriate code to open the file.

Certainly you could substitute parameters for functions in the table,
provided that parameters were sufficient (you might end up using the
parameters to dispatch a different function, which would duplicate effort).
  Based upon the information given, I couldn't venture a guess at this
point.

Regards,

···

On Thu, 28 Mar 2002 14:35:32 -0800 Jeff Shannon wrote:

Cliff Wells wrote:
> class SomeClass(wxSomeBaseClass):
> ...
> self.dispatchTable = {}
> menuItems = [ # this could be created from a file or something
> ("Some item", someFunction),
> ("Another item", anotherFunction),
> ]
> menu = wxMenu()
> for label, function in menuItems:
> id = wxNewId()
> menu.Append(id, label)
> EVT_MENU(self, id, self.someMethod)
> self.dispatchTable[id] = function

> ...
>
> def someMethod(self, event):
> # do some stuff
> ...
> self.dispatchTable[event.GetId()]()

Of course, this begs the question of why not simply use:

    for label, function in menuitems:
        id = wxNewId()
        menu.Append(id, label)
        EVT_MENU(self, id, function)

and let wxWindows do the dispatching *for* you, since that's what it's
designed for... :wink: On the other hand, if the point is to run the same
function with a different parameter for each menu item, then your
proposal would be ideal, substituting a dictionary of the desired
parameters for your dictionary of functions.

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 x308 (800) 735-0555 x308