首页 > 解决方案 > 单击在多个文件中读取类的按钮时如何创建多个 Tkinter 窗口?

问题描述

最近我一直在使用 Tkinter 开发一个 python gui,我的代码变得很长而且很难理解。因此,我决定为程序的不同页面将其分解为不同的文件。我有一个简短版本的代码,它似乎在我第一次尝试访问第一页时可以工作,但是在我返回主菜单后,它给了我一个错误,说我没有定义函数。

主文件

try:
    import Tkinter as tk
except:
    import tkinter as tk

from PageOne import *


class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(StartPage)
        self.title('hey there')
        self.geometry('1000x1000')

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="Start page", font=('Helvetica', 18, "bold")).pack(side="top", fill="x", pady=5)
        tk.Button(self, text="Go to Start Page", command=lambda: master.switch_frame(Page_One)).pack()
        tk.Button(self, text="Go to page two", command=lambda: master.switch_frame(PageTwo)).pack()


class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Frame.configure(self, bg='blue')
        tk.Label(self, text="Page one", font=('Helvetica', 18, "bold")).pack(side="top", fill="x", pady=5)
        tk.Button(self, text="Go back to start page",
                  command=lambda: master.switch_frame(StartPage)).pack()


class PageTwo(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Frame.configure(self, bg='red')
        tk.Label(self, text="Page two", font=('Helvetica', 18, "bold")).pack(side="top", fill="x", pady=5)
        tk.Button(self, text="Go back to start page", command=lambda: master.switch_frame(StartPage)).pack()


if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

PageOne.py

try:
    import Tkinter as tk
except:
    import tkinter as tk

from main import StartPage

class Page_One(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Frame.configure(self, bg='blue')
        tk.Label(self, text="Page one", font=('Helvetica', 18, "bold")).pack(side="top", fill="x", pady=5)
        tk.Button(self, text="Go back to start page", command=lambda: master.switch_frame(StartPage)).pack()

标签: pythontkinter

解决方案


这条线有问题:

self._frame = new_frame

您正在将一个传递给switch_frame,但您想调用pack一个实例

有两种方法可以解决此问题。

  1. 调用 master.switch_frame(StartPage()))
  2. 将上面的行更改为self._frame = new_frame()

(注意()在这两种情况下)。

您的第二个问题是这种模式行不通:

 master.switch_frame(StartPage())).pack()

这是因为您的函数switch_frame没有返回值。因此,代码没有任何东西可以打包!同样,您有一些选择:

  1. 将代码更改为master.switch_frame(StartPage()))
  2. switch_frames结束self._frame = new_frame; return self._frame而不是包含.pack()在该函数中。

应该注意的是,您最好使用master.switch_frame(StartPage()))(不带.pack())。这是因为您可能不希望应用程序让其余代码访问您的当前_frame值。


推荐阅读