li2150
li2150

Reputation: 13

python tkinter: Custom menu while pulling down

I'm learning creating software with Python and Tkinter. Now I need to change menu items for different conditions, but could not find an easy way to do it. Well, let me try to explain my question clearly using an example:

enter image description here

Like shown in the figure, I have a listbox on the left and a listbox on the right. I also have a menu to move the items around, the commands are "move to right", "move to left" and "exchange". The following conditions are considered:

  1. When I only get items selected in left listbox, I want only the command "move to right" enabled, like shown in the figure.
  2. When I only get items selected in right listbox, I want only the command "move to left" enabled.
  3. When I get items selected in both listboxes, I want all commands enabled.
  4. When I get no item selected, I want all commands disabled.

I know I can get the work done by binding events "ListboxSelect" and "Button-1" to some functions, and then use the functions to configure the menu. But it is really a complex work when I have five listboxes in the actual software. So I am wondering whether there is an easy way to do this, like overloading some functions in tkinter.Menu class (I tried overloading post(), grid(), pack() and place(), none of them works).

Any idea is welcomed.

Upvotes: 0

Views: 1058

Answers (1)

Felipe
Felipe

Reputation: 3149

I think what you want to use is the postcommand to modify the menu as appropriate. If you're going to have multiple listboxes, the simplest solution may be to implement your own class. Here's a rough idea:

class EditMenu(Tkinter.Menu):

    def __init__(self, parent, listboxes, **kw):
        self.commandhook = kw.get('postcommand', None)
        kw['postcommand'] = self.postcommand
        super(EditMenu, self).__init__(parent, **kw)
        self.listboxes = listboxes
        self.add_command(label="Move to right", command=self.move_to_right)
        self.add_command(label="Move to left", command=self.move_to_left)
        self.add_command(label="Exchange", command=self.exchange)

    def postcommand(self):
        for i in xrange(3):
            # do some checks for each entry
            # and set state to either Tkinter.DISABLED or Tkinter.NORMAL
            self.entryconfig(i, state=state)
        if self.commandhook is not None:
            self.commandhook()

    # Implement your three functions here

If you start to add more items, probably what you'll want to do is create a class for each menu item. In that class you could put in the logic for enable/disable and the callback function implementation. Comment if you'd like to see an example.

Upvotes: 1

Related Questions