使用for循环创建tkinter菜单失败

时间:2016-09-17 23:53:12

标签: python tkinter menu

我想使用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()  

0 个答案:

没有答案