python - 从单独的类调用 GUI 方法/子类
问题描述
我正在尝试创建一个脚本来创建一个 GUI 类的实例,它本身具有子类来表示我想要显示的各种页面。
目标是创建一个调用特定 GUI 页面来显示的序列文件,一旦显示该 GUI 页面并单击按钮,它将运行序列文件中的序列,然后指示要显示哪些 GUI 页面。
Seqeuncer 看起来像这样(显示测试页的标准已简化)
import gui
class Sequencer():
def __init__(self):
pass
def run_gui(self):
# Create instance of the Test GUI
self.my_gui = gui.TestGUI()
self.my_gui.mainloop()
def run_test(self, entry):
if x = 1:
gui.TestGUI().show_page(PageOne)
if x = 2:
gui.TestGUI().show_page(PageTwo)
GUI 看起来像:
import sequencer
class TestGUI(tk.Tk):
def __init__(self):
# Initialize the container
tk.Tk.__init__(self)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
# Make the container a fixed size
tk.Tk.resizable(self, False, False)
# Set up the pages for the GUI
self.pages = {}
list_of_pages = [
PageOne,
PageTwo
]
for P in list_of_pages:
frame = P(container, self)
self.pages[P] = frame
frame.grid(row=0, column=0, sticky="nsew")
# Set the Main Page
self.show_page(MainPage)
def show_page(self, page):
frame = self.pages[page]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
entry = tk.Entry(self, width=40, font="Arial 16", justify="center")
entry.place(relx=0.5, rely=0.5, anchor="center")
# Create Binding for the Return Key
entry.bind("<Return>", lambda event: sequencer.Sequencer().run_test(entry.get()))
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
然后,我创建了一个顶级脚本 (main.py),它创建了 Sequencer 的一个实例并运行了 gui。我没有显示应该显示的页面,而是出现错误。
我做错了吗?
解决方案
您不应该创建Sequencer
. 相反,传递一个引用或为其他类提供访问实例的方法。
我要做的是将音序器传递给您的 GUI,如下所示:
class Sequencer():
def run_gui(self):
...
self.my_gui = gui.TestGUI(sequencer=self)
...
class TestGUI(tk.Tk):
def __init__(self, sequencer):
self.sequencer = sequencer
...
因为您的每个子页面都被指定TestGUI
为控制器的实例,所以您可以通过删除导入来引用现有的排序器,然后使用控制器来获取对排序器的引用:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.controller = controller
...
entry.bind("<Return>", lambda event: self.controller.sequencer.run_test(entry.get()))
但是,如果替换lambda
为适当的函数,代码将更易于阅读和调试。我发现这是一个很好的经验法则,lambda
除非你绝对必须,否则永远不要使用。在这种情况下,使用lambda
.
例子:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.entry = tk.Entry(...)
self.entry.bind("<Return>", self.run_test)
...
def run_test(self):
data = self.entry.get()
self.controller.sequencer.run_test(data)
这样,对代码进行调试就变得容易得多,因为您可以在调用之前检查数据run_test
。在这个简单的情况下,这可能没有必要,但如果你养成了这样编码的习惯,当你发现自己编写更复杂的命令时它会派上用场。
您还需要更改run_test
函数以重用现有的 TestGUI 实例,而不是每次都创建一个新实例。
def run_test(self, entry):
...
self.mygui.show_page(PageOne)
...
推荐阅读
- sql - 需要在我的查询 oracle r12 中删除重复项
- javascript - 有没有办法从反应 redux 中的一个动作调用另一个动作
- c - 如何使 .txt 文件的最后一行不被打印两次?
- c# - 使用 specflow Specrun 构建硒解决方案时出现错误
- javascript - Javascript: Removing part of a string ( get date string )
- reactjs - 到达路由器:在功能单击时重定向到 url
- ios - 表视图数据被覆盖
- javascript - 坦克!Unity 目前正在尝试添加一个健康拾取项目
- python - 使用正则表达式从熊猫系列字符串中删除单词
- java - 无法延迟初始化角色集合。简单的 JPA findById