我已经使用Tkinter创建了一个具有不同菜单选项的GUI(下面会生成类似的示例)。每个菜单都有不同的命令,单击这些命令时会创建一个新框架。现在发生的事情是,如果我切换到另一个命令,新帧将堆叠在当前帧之下而不是替换旧帧。
我想知道前进的最佳方式是什么。
import Tkinter as tkinter
root = tkinter.Tk()
root.minsize(400,300)
welcome = tkinter.Frame(root).grid()
label = tkinter.Label(welcome, text="Welcome to my program").grid(row=0, column=3)
button = tkinter.Button(welcome,text="Exit",command=root.destroy).grid(row=3, column=1)
def newFrame():
newFrame = tkinter.Frame(root).grid()
newFrame_name = tkinter.Label(newFrame, text="This is another frame").grid()
menu = tkinter.Menu(root)
root.config(menu=menu)
main_menu = tkinter.Menu(menu)
menu.add_cascade(label="Main Menu", menu= main_menu)
main_menu.add_command(label="New Frame", command=newFrame)
main_menu.add_command(label="Another Frame", command=newFrame)
#menu.add_command(label="Exit", command=root.destroy, menu= filemenu)
root.mainloop()
现在,如果我在New Frame和Another Frame之间切换,窗口会叠加,但我想要一个窗口替换另一个窗口。
有什么想法吗?感谢。
答案 0 :(得分:4)
这是我最近使用的一种方法的最小例子;密钥位于PythonGUI.show_frame
,它将适当的框架移动到前面以供显示。
import Tkinter as tk
class BaseFrame(tk.Frame):
"""An abstract base class for the frames that sit inside PythonGUI.
Args:
master (tk.Frame): The parent widget.
controller (PythonGUI): The controlling Tk object.
Attributes:
controller (PythonGUI): The controlling Tk object.
"""
def __init__(self, master, controller):
tk.Frame.__init__(self, master)
self.controller = controller
self.grid()
self.create_widgets()
def create_widgets(self):
"""Create the widgets for the frame."""
raise NotImplementedError
class ExecuteFrame(BaseFrame):
"""The application home page.
Attributes:
new_button (tk.Button): The button to switch to HomeFrame.
"""
def create_widgets(self):
"""Create the base widgets for the frame."""
self.new_button = tk.Button(self,
anchor=tk.W,
command=lambda: self.controller.show_frame(HomeFrame),
padx=5,
pady=5,
text="Home")
self.new_button.grid(padx=5, pady=5, sticky=tk.W+tk.E)
class HomeFrame(BaseFrame):
"""The application home page.
Attributes:
new_button (tk.Button): The button to switch to ExecuteFrame.
"""
def create_widgets(self):
"""Create the base widgets for the frame."""
self.new_button = tk.Button(self,
anchor=tk.W,
command=lambda: self.controller.show_frame(ExecuteFrame),
padx=5,
pady=5,
text="Execute")
self.new_button.grid(padx=5, pady=5, sticky=tk.W+tk.E)
class PythonGUI(tk.Tk):
"""The main window of the GUI.
Attributes:
container (tk.Frame): The frame container for the sub-frames.
frames (dict of tk.Frame): The available sub-frames.
"""
def __init__(self):
tk.Tk.__init__(self)
self.title("Python GUI")
self.create_widgets()
self.resizable(0, 0)
def create_widgets(self):
"""Create the widgets for the frame."""
# Frame Container
self.container = tk.Frame(self)
self.container.grid(row=0, column=0, sticky=tk.W+tk.E)
# Frames
self.frames = {}
for f in (HomeFrame, ExecuteFrame): # defined subclasses of BaseFrame
frame = f(self.container, self)
frame.grid(row=2, column=2, sticky=tk.NW+tk.SE)
self.frames[f] = frame
self.show_frame(HomeFrame)
def show_frame(self, cls):
"""Show the specified frame.
Args:
cls (tk.Frame): The class of the frame to show.
"""
self.frames[cls].tkraise()
if __name__ == "__main__":
app = PythonGUI()
app.mainloop()
exit()
答案 1 :(得分:2)
有两种基本方法可以解决问题:
将所有帧堆叠在一起(例如:放入相同的网格单元格,或使用相同选项的place
),然后提升应该对顶部可见的帧堆栈(使用frame.lift()
)。该答案的一个例子是:Switch between two frames in tkinter
每当您展示新框架时,请销毁(使用.destroy()
或隐藏(使用pack_forget
或grid_forget
)旧框架。
答案 2 :(得分:2)
我有一个简单的例子。对不起,因为我不知道如何通过class
来执行此代码。我只是使用简单的代码。但它的确有效!
:d
这是:
from Tkinter import *
def gantihal(frame):
frame.tkraise()
root = Tk()
f1 = Frame(root)
f2 = Frame(root)
f3 = Frame(root)
f4 = Frame(root)
for frame in (f1, f2, f3, f4):
frame.grid(row=0, column=0, sticky='news')
Button(f1, text='goto frame 2', command=lambda:gantihal(f2)).pack()
Label(f1, text='this is in frame 1').pack()
Label(f2, text='this is in frame two').pack()
Button(f2, text='goto frame 3', command=lambda:gantihal(f3)).pack()
Label(f3, text='this is in frame 3').pack(side='left')
Button(f3, text='next frame :)', command=lambda:gantihal(f4)).pack(side='left')
Label(f4, text='fourth frame').pack()
Button(f4, text='goto 1st frame', command=lambda:gantihal(f1)).pack()
gantihal(f1)
root.mainloop()