Python Tkinter子菜单单选按钮

时间:2014-02-16 21:55:30

标签: python tkinter submenu

我在创建适合我的应用程序需求的菜单时遇到问题。我正在创建一个应用程序,要求用户在源菜单中选择要比较的可能项目。

现在我的菜单组织看起来像是

FILE | EDIT | OPTIONS | SOURCE | HELP

我的问题是,源内的选择数量非常大(约100)并且需要快速导航(<5秒)或者我的应用程序的目标受众可能不会使用它。

我想到的解决方案是将选项嵌套在它们来自的数据结构下面。实际上,这意味着我可以将Source选项和子选项视为两个列表:

["Data1", "Data2", "Data3"] 

[["Option1_1", "Option1_2", "Option1_3"],
["Option2_1","Option2_2","Option2_3"],
["Option3_1","Option3_2","Option3_3"]]

我进行了广泛搜索,无法找到如何在Tkinter中有效创建子菜单。当我得到radiobuttons的子菜单(检查按钮也可以工作)时,按钮单击不会激活命令,这不是一个可行的解决方案。

我想要做的是创建一个类似于

的菜单
FILE | SOURCE | ETC...
          Data1    |
               Option1_1
               Option1_2
               Option1_3
         Data2    |
         Data3

我该怎么做?最好同时将按钮存储到列表中,然后将它们附加到菜单中,以便我可以调用select和取消选择是否需要? Radiobuttons或checkbuttons可以使用,如果我在创建后仍然可以访问它们,那么首选支票按钮。

谢谢

以下是非工作代码的一个示例:

from Tkinter import *
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.makeMenu(master)

    def makeMenu(self, parent):
        menuBar = Frame(parent, relief = 'raised', borderwidth = 1)
        fileMenu = Menubutton(menuBar, text = "File")
        fileMenu.pack(side = 'left')
        fileMenu.menu = Menu(fileMenu, tearoff = 0)
        load = Menubutton(fileMenu.menu, text="Load")
        load.pack(anchor=W)
        source = Menubutton(fileMenu.menu, text="Source")
        source.pack(anchor=W)
        source.menu = Menu(source, tearoff = 0)
        self._listi = ["who", "what", "where", "how"]
        self._buttonList = []
        for l in self._listi:
            c = Checkbutton(master = source.menu, text=l, command=lambda arg0=l: self.test(arg0))
            self._buttonList.append([l, c])
            c.pack()
        save = Button(master=fileMenu.menu, text="Save")
        save.pack(anchor=W)
        exit = Button(master=fileMenu.menu, text="Exit", command = self.quit)
        exit.pack()
        fileMenu['menu'] = fileMenu.menu
        menuBar.pack()

    def test(self, arg0):
        for b in self._buttonList:
            if arg0 != b[0]:
                b[1].deselect()
            elif arg0 == b[0]:
                b[1].select()


# create app
myApp = App()

# start program
myApp.mainloop()

1 个答案:

答案 0 :(得分:1)

您无法将CheckbuttonButton个实例添加到菜单中。您必须使用add_checkbuttonadd_radiobuttonadd_command方法。此外,您不需要从框架和menubuttons创建菜单栏 - 您可以将菜单直接附加到窗口。此外,您无需以编程方式选择或取消选择由tkinter处理的checkbuttons或radiobutton。

我修改了你的代码来说明:

from Tkinter import *
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.makeMenu(master)

    def makeMenu(self, parent):
        menuBar = Menu(parent)
        parent.configure(menu=menuBar)
        fileMenu = Menu(menuBar)
        sourceMenu = Menu(menuBar)
        menuBar.add_cascade(label="File", menu=fileMenu)
        fileMenu.add_command(label="Load")
        fileMenu.add_cascade(label="Source", menu=sourceMenu)
        self._listi = ["who","what","where","how"]
        for l in self._listi:
            sourceMenu.add_checkbutton(label=l, command=lambda arg0=l: self.test(arg0))
        fileMenu.add_command(label="Save")
        fileMenu.add_command(label="Exit", command=self.quit)


    def test(self, arg0):
        print "you clicked on", arg0


# create app
root = Tk()
myApp = App(root)

# start program
myApp.mainloop()

请注意,我还添加了一行代码来创建根窗口,然后将该根窗口传递给应用程序的构造函数。

相关问题