如何切换到主框架
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
中。这样就避免了尝试导入主文件的问题,也让主文件更有条理
我试图在用户按下 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
中。这样就避免了尝试导入主文件的问题,也让主文件更有条理