Jednym ze sposobów jest układanie ramek jedna na drugiej, a następnie można po prostu unieść jedną nad drugą w kolejności układania. Ten na górze będzie tym, który jest widoczny. Działa to najlepiej, jeśli wszystkie ramki mają ten sam rozmiar, ale przy odrobinie pracy można sprawić, że będzie działać z ramkami o dowolnym rozmiarze.
Uwaga : aby to zadziałało, wszystkie widżety dla strony muszą mieć tę stronę (tj .:) self
lub element podrzędny jako element nadrzędny (lub wzorzec, w zależności od preferowanej terminologii).
Oto trochę wymyślony przykład, aby pokazać ogólną koncepcję:
try:
import tkinter as tk
from tkinter import font as tkfont
except ImportError:
import Tkinter as tk
import tkFont as tkfont
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
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 F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Jeśli koncepcja tworzenia instancji w klasie jest myląca lub jeśli różne strony wymagają różnych argumentów podczas konstruowania, możesz jawnie wywołać każdą klasę osobno. Pętla służy głównie do zilustrowania faktu, że każda klasa jest identyczna.
Na przykład, aby utworzyć klasy indywidualnie, możesz usunąć pętlę (za for F in (StartPage, ...)
pomocą tego:
self.frames["StartPage"] = StartPage(parent=container, controller=self)
self.frames["PageOne"] = PageOne(parent=container, controller=self)
self.frames["PageTwo"] = PageTwo(parent=container, controller=self)
self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")
self.frames["PageOne"].grid(row=0, column=0, sticky="nsew")
self.frames["PageTwo"].grid(row=0, column=0, sticky="nsew")
Z biegiem czasu ludzie zadawali inne pytania, używając tego kodu (lub samouczka online, który skopiował ten kod) jako punktu wyjścia. Możesz przeczytać odpowiedzi na następujące pytania: