我知道如何创建基本的Tkinter菜单栏,但我不知道如何实现它,以便菜单出现在多帧GUI的每一帧上。
我将使用菜单栏在帧之间切换。因此,我需要在菜单命令中运行controller.show_frame
命令。我目前正在使用按钮来执行此操作。
我无法找到这样做的方法,因为(据我所知)菜单必须在框架类而不是tk.Tk
类中创建,以便允许我运行该功能。
这是代码:
""" Messing about with tkinter """
import tkinter as tk
LARGE_FONT = ("Verdana", 12)
class Window(tk.Tk):
""" Main class """
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for frame in (Main, Checker):
current_frame = frame(container, self)
self.frames[frame] = current_frame
current_frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Main)
def show_frame(self, cont):
""" Raises a particular frame, bringing it into view """
frame = self.frames[cont]
frame.tkraise()
def qprint(quick_print):
""" Function to print a string """
print(quick_print)
class Main(tk.Frame):
""" Main frame of program """
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Main Menu", font=LARGE_FONT)
label.pack(pady=10, padx=10)
class Checker(tk.Frame):
""" Password Strength Checker """
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Password Checker", font=LARGE_FONT)
label.pack(pady=10, padx=10)
APP = Window()
APP.geometry("350x200")
APP.mainloop()
答案 0 :(得分:2)
“必须在框架类而不是tk.Tk类中创建菜单,以便允许我运行 功能“。
我不认为这是真的,请参阅下面为Menu
小部件创建Toplevel
的示例:
import tkinter as tk
if __name__ == '__main__':
root = tk.Tk()
root.withdraw()
toplevel = tk.Toplevel(root)
# create a toplevel menu
menubar = tk.Menu(toplevel)
menubar.add_command(label="Hello!")
menubar.add_command(label="Quit!", command=root.quit)
# display the menu
toplevel.config(menu=menubar)
root.mainloop()
或者,你可以在的框架中为创建菜单,条件是他们的父母是Toplevel
- 就像。
在下面的示例中,当选择菜单项时,Root
的菜单会在Root
的菜单及其子FrameWithMenu
对象的菜单之间跳转:
import tkinter as tk
class Root(tk.Tk):
def __init__(self):
super().__init__()
self.title("The Root class with menu")
self.a_frame = FrameWithMenu(self)
self.create_menu()
def create_menu(self):
self.menubar = tk.Menu(self)
self.menubar.add_command(label="Root", command=self.a_frame.replace_menu)
self['menu'] = self.menubar
class FrameWithMenu(tk.Frame):
def __init__(self, master):
super().__init__(master)
def replace_menu(self):
""" Overwrite parent's menu if parent's class name is in _valid_cls_names.
"""
_parent_cls_name = type(self.master).__name__
_valid_cls_names = ("Tk", "Toplevel", "Root")
if _parent_cls_name in _valid_cls_names:
self.menubar = tk.Menu(self)
self.menubar.add_command(label="Frame", command=self.master.create_menu)
self.master['menu'] = self.menubar
if __name__ == '__main__':
root = Root()
root.mainloop()
答案 1 :(得分:1)
我找到了自己问题的答案。我需要做的就是使用controller
参数创建菜单,该参数引用tk.Tk
类。
class Main(tk.Frame):
""" Main frame of program """
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Main Menu", font=LARGE_FONT)
label.pack(pady=10, padx=10)
menubar = tk.Menu(controller)
menubar.add_command(label="Checker", command=lambda: controller.show_frame(Checker))
controller.config(menu=menubar)