【问题标题】:Switch between two frames in tkinter in separates files在分隔文件中的 tkinter 中的两个帧之间切换
【发布时间】:2021-08-31 15:48:28
【问题描述】:

我想修改来自:Switch between two frames in tkinter 的代码。我将三个类放在三个单独的文件中,但是当我从 pageOne.py 调用 master.switch_frame(master.StartPage) 时,会出现错误: 返回 getattr(self.tk, attr) AttributeError: '_tkinter.tkapp' 对象没有属性 'StartPage'

有人可以帮我解决这个错误吗?我很感激任何建议。

代码是:

main.py

#take from: https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter
# Multi-frame tkinter application v2.3
import tkinter as tk
import pageOne as p1
import pageTwo as p2

class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(StartPage)

    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        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="This is the start page").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Open page one",
                  command=lambda: master.switch_frame(p1.PageOne)).pack()
        tk.Button(self, text="Open page two",
                  command=lambda: master.switch_frame(p2.PageTwo)).pack()

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

pageOne.py

# Multi-frame tkinter application v2.3
import tkinter as tk

class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page one").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page",
                  command=lambda: master.switch_frame(master.StartPage)).pack()

if __name__ == "__main__":
    app = PageOne()
    app.mainloop()# Multi-frame tkinter application v2.3
import tkinter as tk

class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page one").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page",
                  command=lambda: master.switch_frame(master.StartPage)).pack()

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

    enter code here

pageTwo.py

# Multi-frame tkinter application v2.3
import tkinter as tk

class PageTwo(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page two").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page",
                  command=lambda: master.switch_frame(master.StartPage)).pack()

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

谢谢布莱恩·奥克利。最后的工作代码是:

main.py

#take from: https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter
# Multi-frame tkinter application v2.3
import tkinter as tk

from StartPage import StartPage
from pageOne import PageOne
from pageTwo import PageTwo

pages = {
    "StartPage": StartPage, 
    "PageOne": PageOne, 
    "PageTwo": PageTwo
}

class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame("StartPage")

    def switch_frame(self, page_name):
        """Destroys current frame and replaces it with a new one."""
        cls = pages[page_name]
        new_frame = cls(master = self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

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

pageOne.py

# Multi-frame tkinter application v2.3
import tkinter as tk

class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page one").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page", command=lambda: master.switch_frame("StartPage")).pack()

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

pageTwo.py

# Multi-frame tkinter application v2.3
import tkinter as tk

class PageTwo(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page two").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page", command=lambda: master.switch_frame("StartPage")).pack()

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

StartPage.py

# Multi-frame tkinter application v2.3
import tkinter as tk

class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is the start page").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Open page one", command=lambda: master.switch_frame("PageOne")).pack()
        tk.Button(self, text="Open page two", command=lambda: master.switch_frame("PageTwo")).pack()

【问题讨论】:

  • 您希望master.StartPage 是什么?你知道你没有定义这样的东西,因为如果你是那么SampleApp 将包含类似self.StartPage = ...

标签: python file class tkinter frame


【解决方案1】:

我建议将字符串作为参数传递给show_frame。这样,其他文件就不需要导入所有其他类。然后,您可以创建一个供switch_frame 使用的映射。该文件成为唯一需要导入其他页面的文件。

它应该类似于以下代码。在此示例中,我将 StartPage 移动到一个单独的文件中以保持一致性:

from startPage import StartPage
from pageOne import PageOne
from pageTwo import PageTwo

pages = {
    "StartPage": StartPage, 
    "PageOne": PageOne, 
    "PageTwo": PageTwo
}

class SampleApp(tk.Tk):
    ...
    def switch_frame(self, page_name):
        """Destroys current frame and replaces it with a new one."""
        cls = pages[page_name]
        new_frame = cls(master=self)
        ...

您的其他页面不需要导入页面,只需要使用页面名称即可:

class PageTwo(tk.Frame):
    def __init__(self, master):
        ...
        tk.Button(..., command=lambda: master.switch_frame("StartPage")).pack()

【讨论】:

    猜你喜欢
    • 2011-11-24
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    相关资源
    最近更新 更多