如何在多个 windows Tkinter 程序中保持不变的布局?
How to keep a constant layout in multiple windows Tkinter program?
我正在开发一个 Python Tkinter 应用程序,预计会有多个 windows。同时,我想保持某些布局(背景图像,Top/bottom 标签)不变。我尝试设置背景图片 (b_image) 和左上角标签 (topleft_label),但它没有显示。有人可以看看这个片段并建议如何实现吗?
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1024
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Sales System") # set the title of the main window
self.geometry("%dx%d+0+0" % (WIDTH, HEIGHT)) # set size of the main window to 300x300 pixels
container = tk.Frame(self)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(container, image=b_image)
b_label.place(relwidth=1, relheight=1)
topleft_label = tk.Label(container, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
app = MainApp()
app.mainloop()
方法
解决此问题的最佳方法很可能是制作一个 base_frame
class,其中包含图像和 topleft_label
、"Welcome - Login Screen"。这意味着 StartPage
object 可以继承 base_frame
class 的背景图像。
代码
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1366
class MainApp():
def __init__(self, master):
self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
崩溃
开始代码
使这个class系统运行的代码是这样的:
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
英文行if __name__ == '__main__':
也大致翻译为:If the program is 运行 and not imported。因此,如果程序是 运行 且未导入,则 运行 主要功能。
root = tk.Tk()
只是在根变量中创建一个 Tk window。
main_app = MainApp(root)
初始化 main_app object 其主人是根变量
root.mainloop()
启动 tkinter 循环。
MainApp Class
MainApp Class 首先将其标题设置为 "Sales System" 并将几何图形重置为在 HEIGHT & WIDTH:
中定义的值
self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
然后 self.frames
字典和 start_page
被初始化并且 start_page
被放置在 self.frames
:
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
然后设置start_page来填充整个window:
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
然后我们显示第一页:
self.show_frame(StartPage)
然后创建 show_frame
函数
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
base_frame Class
前 3 行创建一个 class,其值与 tk.Frame
object 相同,参数和关键字参数通过:
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
然后创建图像标签:
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
b_label.image = b_image
行用于确保图像由标签显示(从函数内加载时这是必需的)。
然后我们创建默认的topleft_label
:
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
您可能希望更新此代码以便将来更改这些标签,只需将 topleft_label
替换为 self.topleft_label
并将 b_label
替换为 self.b_label
起始页Class
这个 class 与您之前创建的 class 没有太大区别:
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
唯一的区别是它不是继承自 tk.Frame
,而是继承自 base_frame
class。
我正在开发一个 Python Tkinter 应用程序,预计会有多个 windows。同时,我想保持某些布局(背景图像,Top/bottom 标签)不变。我尝试设置背景图片 (b_image) 和左上角标签 (topleft_label),但它没有显示。有人可以看看这个片段并建议如何实现吗?
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1024
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Sales System") # set the title of the main window
self.geometry("%dx%d+0+0" % (WIDTH, HEIGHT)) # set size of the main window to 300x300 pixels
container = tk.Frame(self)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(container, image=b_image)
b_label.place(relwidth=1, relheight=1)
topleft_label = tk.Label(container, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
app = MainApp()
app.mainloop()
方法
解决此问题的最佳方法很可能是制作一个 base_frame
class,其中包含图像和 topleft_label
、"Welcome - Login Screen"。这意味着 StartPage
object 可以继承 base_frame
class 的背景图像。
代码
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1366
class MainApp():
def __init__(self, master):
self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
崩溃
开始代码
使这个class系统运行的代码是这样的:
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
英文行if __name__ == '__main__':
也大致翻译为:If the program is 运行 and not imported。因此,如果程序是 运行 且未导入,则 运行 主要功能。
root = tk.Tk()
只是在根变量中创建一个 Tk window。
main_app = MainApp(root)
初始化 main_app object 其主人是根变量
root.mainloop()
启动 tkinter 循环。
MainApp Class
MainApp Class 首先将其标题设置为 "Sales System" 并将几何图形重置为在 HEIGHT & WIDTH:
中定义的值 self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
然后 self.frames
字典和 start_page
被初始化并且 start_page
被放置在 self.frames
:
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
然后设置start_page来填充整个window:
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
然后我们显示第一页:
self.show_frame(StartPage)
然后创建 show_frame
函数
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
base_frame Class
前 3 行创建一个 class,其值与 tk.Frame
object 相同,参数和关键字参数通过:
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
然后创建图像标签:
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
b_label.image = b_image
行用于确保图像由标签显示(从函数内加载时这是必需的)。
然后我们创建默认的topleft_label
:
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
您可能希望更新此代码以便将来更改这些标签,只需将 topleft_label
替换为 self.topleft_label
并将 b_label
替换为 self.b_label
起始页Class
这个 class 与您之前创建的 class 没有太大区别:
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
唯一的区别是它不是继承自 tk.Frame
,而是继承自 base_frame
class。