如何在多个Windows Tkinter程序中保持恒定的布局?

问题描述 投票:0回答:1

我正在研究一个有望有多个窗口的Python Tkinter应用程序。同时,我想保持某些布局(背景图像,顶部/底部标签)恒定。我尝试设置背景图像(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()
python tkinter background multiple-inheritance tkinter-layout
1个回答
0
投票

方法

解决此问题的最佳方法很可能是创建一个base_frame类,其中包含图像和topleft_label“欢迎-登录屏幕”。这意味着StartPage对象可以继承base_frame类的背景图像。


代码

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()

细分

启动代码

使此类系统运行的代码如下:

def main():
    root = tk.Tk() # MainApp()
    main_app = MainApp(root)
    root.mainloop()

if __name__ == '__main__':
    main()

if __name__ == '__main__':行用英语也大致翻译:如果程序正在运行但未导入。因此,如果程序已运行但未导入,请运行main函数。

[root = tk.Tk()只是在根变量内部创建一个Tk窗口。

[main_app = MainApp(root)初始化main_app对象,其主对象为根变量

[root.mainloop()开始tkinter循环。

MainApp类

MainApp类首先将其标题设置为“销售系统”,然后将几何图形重置为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.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类

[前三行创建一个类,该类的值与tk.Frame对象的值相同,并且args和关键字args传递给:

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

StartPage类

该类与您之前创建的类没有太大不同:

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类继承。

© www.soinside.com 2019 - 2024. All rights reserved.