【发布时间】:2019-09-09 06:02:11
【问题描述】:
我有一个带有主菜单栏的 Tkinter GUI,使用 Tkinter 的 Menu 小部件。我想在发布子菜单之前执行代码(通过.add_cascade() 级联的另一个菜单项),以便我可以在显示之前动态更改其内容。我使用Menu 的 postcommand 参数进行了这项工作,但我注意到使用它的效率非常低;当点击 anyone 子菜单时,会调用 all 子菜单的 postcommand 回调,而不仅仅是为具有回调而创建的特定子菜单。即使点击没有菜单项的菜单栏也会执行所有回调,即使没有创建子菜单。
这是来自 Menu 模块及其 postcommand 参数的预期行为吗?我不明白为什么在为下拉菜单创建单独的 Menu 实例后仍然会发生这种情况。
我已经尝试使用 Tk.Menu 的本地方法,但是当简单地单击菜单栏项以调出级联菜单时,它们都不会被调用。即使 .add_cascade() 接受一个“命令”参数,它也只会在不包含 .add_cascade() 的“菜单”参数或者如果它是一个 lambda 表达式(这两者都导致没有子菜单)时调用它提供的可调用对象单击该项目时显示)。 (您可以使用下面的test() 函数看到这一点。)
这是一个显示此行为的简单应用:
import Tkinter as Tk
import time
def test(): print 'test'
class firstMenu( Tk.Menu ):
def __init__( self, parent, tearoff=False ):
Tk.Menu.__init__( self, parent, tearoff=tearoff, postcommand=self.repopulate )
def repopulate( self ):
print 'repopulating firstMenu'
time.sleep( 2 ) # Represents some thinking/processing
# Clear all current population
self.delete( 0, 'last' )
# Add the new menu items
self.add_command( label='Option 1.1' )
self.add_command( label='Option 1.2' )
class secondMenu( Tk.Menu ):
def __init__( self, parent, tearoff=False ):
Tk.Menu.__init__( self, parent, tearoff=tearoff, postcommand=self.repopulate )
def repopulate( self ):
print 'repopulating secondMenu'
time.sleep( 2 ) # Represents some thinking/processing
# Clear all current population
self.delete( 0, 'last' )
# Add the new menu items
self.add_command( label='Option 2.1' )
self.add_command( label='Option 2.2' )
class Gui( object ):
def __init__( self ): # Create the TopLevel window
root = Tk.Tk()
root.withdraw() # Keep the GUI minimized until it is fully generated
root.title( 'Menu Test' )
# Create the GUI's main program menus
menubar = Tk.Menu( root )
menubar.add_cascade( label='File', menu=firstMenu( menubar ), command=test )
menubar.add_cascade( label='Settings', menu=secondMenu( menubar ) )
root.config( menu=menubar )
root.deiconify() # Brings the GUI to the foreground now that rendering is complete
# Start the GUI's mainloop
root.mainloop()
root.quit()
if __name__ == '__main__': Gui()
如果您单击菜单栏上的任意位置,则会调用两个 postcommand 回调。当您单击相应的菜单项时,我需要(并且希望)只调用其中一个。
我不确定它是否相关,但我也在另一个小部件上使用与上下文菜单相同的菜单项。所以他们的 .post() 方法也需要能够在菜单显示之前触发同样的回调。
如果您有任何见解,请提前致谢。
【问题讨论】:
标签: python-2.7 tkinter callback menu submenu