Tkinter:GUI内的窗口导航

时间:2016-01-13 10:45:31

标签: python user-interface tkinter navigation

我几天前发布了一个关于此主题的问题,但由于我在该问题中的示例代码错误,我删除了该主题以提供更清晰的示例代码。 在Tkinter构建的GUI中浏览不同页面/窗口的最佳实践是什么?简单地说,我希望能够通过我的菜单栏中的命令在我的应用程序中浏览不同的页面。我想避免将页面堆叠在一起,并且使用grid_remove()pack_forget()的方法比我更好。 我在这里找到的唯一其他教程使用堆叠方法和lift()。还有其他更好的方法吗?

import tkinter as tk
from tkinter import *


class MainWin(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.page_1 = Page1(self.parent)
        self.page_2 = Page2(self.parent)

        self.init_UI()

    def init_UI(self):
        menubar = Menu(self.parent)
        self.parent.config(menu=menubar)
        self.parent.title('Frame Switching test app')
        file_menu = Menu(menubar)
        pages_menu = Menu(menubar)
        menubar.add_cascade(label='File', menu=file_menu)
        file_menu.add_command(label='Exit', command=self.on_exit)
        menubar.add_cascade(label='Pages', menu=pages_menu)
        pages_menu.add_command(label='Pages 1', command=self.page_1.show)
        pages_menu.add_command(label='Page 2', command=self.page_2.show)

    def on_exit(self):
        self.quit()


class Page1(LabelFrame):
    def __init__(self, parent):
        LabelFrame.__init__(self, parent)
        self.parent = parent
        self.config(text='This is page 1 label Frame')
        self.sample_text = Label(self, text='You are viewing Page 1')

    def show(self):
        self.pack(fill=BOTH, expand=1)
        self.sample_text.grid(in_=self)
        self.lift()

    def close(self):
        self.pack_forget()


class Page2(LabelFrame):
    def __init__(self, parent):
        LabelFrame.__init__(self, parent)
        self.parent = parent
        self.config(text='This is page 2 label Frame')
        self.sample_text = Label(self, text='You are viewing Page 2')

    def show(self):
        self.pack(fill=BOTH, expand=1)
        self.sample_text.grid(in_=self)
        self.lift()

    def close(self):
        self.pack_forget()


def main():
    root = tk.Tk()
    app = MainWin(root)
    root.mainloop()


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:0)

已经有questionanswer,它们展示了如何堆叠帧。要切换到使用grid_forgetpack_forget的模式,您只需更改调用lift的代码,而不是调用适当的"忘记"当前页面上的方法(您需要跟踪),然后添加新窗口。

如果您想按需创建页面,并在不使用时将其销毁,那也很容易。唯一真正的区别是,在您要求之前不要创建页面,并在完成后删除它。否则实现是相同的。

以下是按需创建页面的示例。从this answer中的代码开始,将SampleApp类修改为如下所示:

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        # the container is where we'll pack the current page
        self.container = tk.Frame(self)
        self.container.pack(side="top", fill="both", expand=True)
        self.current_frame = None

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''

        # destroy the old page, if there is one
        if self.current_frame is not None:
            self.current_frame.destroy()

        # create the new page and pack it in the container
        cls = globals()[page_name]
        self.current_frame = cls(self.container, self)
        self.current_frame.pack(fill="both", expand=True)