2013-04-25 54 views
0

我正在学习使用Python和Tkinter创建软件。现在我需要为不同的条件更改菜单项,但找不到一个简单的方法来做到这一点。好吧,让我尝试使用明确的例子来说明我的问题:python tkinter:自定义菜单,同时拉下来

enter image description here

像图中所示,我在左边列表框和右侧的列表框。我还有一个菜单来移动项目,命令是“向右移动”,“向左移动”和“交换”。考虑以下条件:

  1. 当我只在左侧列表框中选择项目时,我只想要启用“移动到右侧”命令,如图所示。
  2. 当我只在右列表框中选中项目时,我只需要启用“向左移动”命令。
  3. 当我在两个列表框中选中项目时,我希望启用所有命令。
  4. 当我没有选择任何项目时,我想禁用所有命令。

我知道我可以通过将事件“ListboxSelect”和“Button-1”绑定到某些功能来完成工作,然后使用这些功能来配置菜单。但是当我在实际的软件中有五个列表框时,它确实是一项复杂的工作。所以我想知道是否有一个简单的方法来做到这一点,比如重载tkinter.Menu类中的一些函数(我尝试了重载post(),grid(),pack()和place(),它们都不起作用。

欢迎任何想法。

回答

1

我想你想使用的是postcommand来适当修改菜单。如果你打算有多个列表框,最简单的解决方案可能是实现你自己的类。这里有一个粗略的想法:

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 

如果你开始添加更多的项目,很可能你会想要做的就是创建一个类为每个菜单项。在那个类中,你可以放入启用/禁用逻辑和回调函数实现。评论你是否想看一个例子。

+0

这正是我需要的!我已经完成了测试中所有条件的测试,它工作得很好。我相信我现在完全理解这个机制。非常感谢! – li2150 2013-04-25 15:40:26