如何切换到主框架

How to switch to a Frame in main

我试图在用户按下 Done 按钮时返回主页。

我有两个文件:

gui_main.py: 主界面有多个Frames

gui_scan.py:当用户按下 Done 按钮时,执行扫描并 returns 返回位于 gui_main.py 的主菜单框架。

问题: 每当我从 gui_main.py 调用一个框架时,我得到一个 KeyError 因为框架不在 main 的框架列表中。 经过大量调试后,我发现我错误地引用了 gui_main.py 中的框架。这就是我引用它的方式:

这是一个 MVCE 等效代码:

#gui_main.py
import tkinter as tk 
from tkinter import ttk 

# External file imports
import gui_scan as scan
from gui_frame import PageFrame


class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        print("Loading")

        print ("Constructing Frames")
        self.frames = {}
        for F in (PageOne,Menu, Settings, scan.PerformScan):
            frame = F(container, self)
            self.frames[F] = frame 

    def show_frame(self, frame_name):
        """ Show @frame_name frame """ 
        self.active_frame = self.frames[frame_name]  # <-- this causes the error
        self.active_frame.tkraise()

# PageOne Frame Class
class PageOne(PageFrame):
    def __init__(self, parent, controller):
    """ ...."""
    # Implementation of this is iirelavant to question

# Menu Frame Class  
class Menu(PageFrame):
    def __init__(self, parent, controller):
    """ ...."""
    # Implementation of this is iirelavant to question

# Settings Frame Class
class Settings(PageFrame):
    def __init__(self, parent, controller):
    """ ...."""
    # Implementation of this is iirelavant to question

if __name__ =="__main__":
    try:
        app = MainWindow()
    except Exception:
        # Problems
        print ("Problems running GUI")

其他文件:

#gui_scan.py
import tkinter as tk 

from gui_frame import PageFrame
import gui_main as main 

class PerformScan(PageFrame):
    def __init__(self, parent, controller):
        PageFrame.__init__(self, parent, controller)
        label = tk.Label(self, padx=0, text="When you are ready press \"Start\" \n", justify=tk.CENTER)
        label.pack()

        button = tk.Button(self, text='Start', command=lambda: self.run_scan())
        button.pack()

    def run_scan(self):
        """ Run a scan"""
        # The scan runs here

        # at the end, have the user press `Done` and go back to Menu from `gui_main.py`
        self.button_frame = tk.Frame(self.final_frame, bg="red")
        self.button = tk.Button(self.button_frame, text = "Done",
            command = lambda:self.controller.show_frame(main.Menu)) # <-- this is wrong,(I think)
        self.button.grid(row = 0, column=3, padx = 5)
        self.button_frame.pack()

调试中: 正在从 main_gui 打印出 self.frames 中的帧:

Frame:  <class '__main__.PageOne'>
Frame:  <class '__main__.Menu'>
Frame:  <class '__main__.Settings'>
Frame:  <class 'gui_scan.PerformScan'>

run_scan(self) 中按下 Done 按钮会传入:

<class 'gui_main.Menu'>

这会产生错误,我会卡在我所在的任何帧,而不是切换回 Menu 帧。

我想通了。

解法:

class PageOne(PageFrame)class Menu(PageFrame)class Settings(PageFrame)从主文件中分离出来,导入到gui_scan.py中。这样就避免了尝试导入主文件的问题,也让主文件更有条理