我想使用tkinter在Python中创建一个动态菜单。最终它将从ini文件中读取以定义菜单选项。当我逐个调用每个add_command()函数时,它按预期工作。 (请参阅我的代码中的"本作品" 注释。)当我在for循环中使用相同的语法时,菜单项都将相同的字符串传递给我的fnPickProgram函数并打开同一个文件。 (参见我的代码中的"这不工作" 注释。)for循环通过两个列表来定义要在菜单上显示的名称(来自strLabel)和文件打开(来自strFile)。硬编码版本执行相同的操作,但使用列表中项目的硬编码引用。我错过了什么?
from tkinter import Tk, Frame, Menu
import subprocess, sys # for calling programs using popen
def fnPickProgram(strFileName):
# Combine file name and the program into strCallThis (skipping bits here for simplicity)
strCallThis = "C:/Program Files (x86)/Notepad++/notepad++.exe " + strFileName
# Call the program to open the file using strCallThis
print("In fnPickProgram running this program: ", strCallThis)
subprocess.Popen(strCallThis)
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Submenu")
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
submenu = Menu(fileMenu)
submenu.add_command(label="New feed", underline=0)
submenu.add_command(label="Bookmarks", underline=1) #underline the o
submenu.add_command(label="Mail", underline=0)
fileMenu.add_cascade(label='Import', menu=submenu, underline=0)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", underline=0, command=self.onExit)
menubar.add_cascade(label="File", underline=0, menu=fileMenu)
# Populate lists with the parts of the menu
vReturn = self.fnMakeMenuBits()
txtMenu = Menu(menubar)
submenu3 = Menu(txtMenu)
for n in range(len(strFile)):
print(n, ": ", strFile[n])
# THIS DOES NOT WORK - When I uncomment the following command I always get the same file opened (the third one).
#submenu3.add_command(label=strLabel[n], underline=0, command=lambda: fnPickProgram(strFile[n]))
# THIS WORKS - using the three add_command() below
# Comment out these 3 lines when using the for loop above
submenu3.add_command(label=strLabel[0], underline=0, command=lambda: fnPickProgram(strFile[0]))
submenu3.add_command(label=strLabel[1], underline=0, command=lambda: fnPickProgram(strFile[1]))
submenu3.add_command(label=strLabel[2], underline=0, command=lambda: fnPickProgram(strFile[2]))
menubar.add_cascade(label="Text Files", underline=1, menu=submenu3)
def fnMakeMenuBits(self):
global strLabel, strFile
strFile = []
strFile.append("C:/Temp/Test.txt")
strFile.append("C:/Temp/ReTest.txt")
strFile.append("C:/Temp/Yahoo.txt")
strLabel = []
strLabel.append("Open Test.txt")
strLabel.append("Open ReTest.txt")
strLabel.append("Open Yahoo.txt")
def onExit(self):
self.quit()
self.master.destroy()
def main():
root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()