Python MWC 模式 GUI - 来自控制器的菜单栏命令 class
Python MWC pattern GUI - Menubar command from controller class
我正在尝试构建一个数据分析工具。我预计这种应用程序会变得很大,所以我遵循 MVC 模式来尽可能地组织它。
我的结果保存在 .csv 文件中,因此目标应该是将它们“导入”到 GUI 中。我想使用“CTRL + O”作为快捷键打开这些文件,当然也可以使用菜单栏中的相应选项。
现在进入实际问题:
点击“CTRL + O”时调用的函数在控制器 class 中并且按预期工作,我可以打开一堆文件并且列表保存每个名称。但是当使用菜单栏时,我不知道如何实现“command=”选项。
这是我的代码:
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.constants import ANCHOR, TRUE
from tkinter import Label, filedialog
from tkinter import ttk
class Model():
# more to come
pass
class View:
def __init__(self, view):
self.view = view
self.view.title("analyzer")
self.view.geometry("640x480")
self.view.resizable(False, False)
# menubar
self.menubar = tk.Menu(self.view)
self.view.config(menu=self.menubar)
self.filemenu = tk.Menu(self.menubar, tearoff=False)
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label="Open", accelerator="Ctrl+O", command=Controller.get_open_filename())
self.filemenu.add_separator()
self.filemenu.add_command(label="Remove", accelerator="Ctrl+R")
self.filemenu.add_command(label="Information", accelerator="Ctrl+I")
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", accelerator="Ctrl+E", command=self.view.quit)
class Controller:
def __init__(self):
self.root = tk.Tk()
self.view = View(self.root)
# keybindings / shortcuts
self.root.bind_all("<Control-e>", lambda event: self.root.quit())
self.root.bind_all("<Control-o>", lambda event: self.get_open_filename())
self.list_of_files = []
def run(self):
self.root.mainloop()
def get_open_filename(self):
self.filename = askopenfilename(title="Select data file", filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
self.list_of_files.append(self.filename)
print(self.list_of_files)
if __name__ == "__main__":
c = Controller()
c.run()
如果有人能给我提示,我将不胜感激,希望我做错了。
谢谢!
您正在尝试从视图对象调用控制器函数,但视图不知道控制器具有该函数。它不知道控制器的存在。
可能有比这更好的方法,但您可以将函数作为参数传递给 View 的构造函数。
通过将 get_open_filename()
函数作为参数传递给 View 的构造函数,您可以将其用作命令。
注意:我调用了参数 func 这样您就可以看到我在做什么。不过我建议给它起一个更好的名字。
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.constants import ANCHOR, TRUE
from tkinter import Label, filedialog
from tkinter import ttk
class Model():
# more to come
pass
class View:
def __init__(self, view, func):
self.view = view
self.view.title("analyzer")
self.view.geometry("640x480")
self.view.resizable(False, False)
# menubar
self.menubar = tk.Menu(self.view)
self.view.config(menu=self.menubar)
self.filemenu = tk.Menu(self.menubar, tearoff=False)
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label="Open", accelerator="Ctrl+O", command=func)
self.filemenu.add_separator()
self.filemenu.add_command(label="Remove", accelerator="Ctrl+R")
self.filemenu.add_command(label="Information", accelerator="Ctrl+I")
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", accelerator="Ctrl+E", command=self.view.quit)
class Controller:
def __init__(self):
self.root = tk.Tk()
self.view = View(self.root, lambda: self.get_open_filename())
# keybindings / shortcuts
self.root.bind_all("<Control-e>", lambda event: self.root.quit())
self.root.bind_all("<Control-o>", lambda event: self.get_open_filename())
self.list_of_files = []
def run(self):
self.root.mainloop()
def get_open_filename(self):
self.filename = askopenfilename(title="Select data file", filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
self.list_of_files.append(self.filename)
print(self.list_of_files)
if __name__ == "__main__":
c = Controller()
c.run()
我正在尝试构建一个数据分析工具。我预计这种应用程序会变得很大,所以我遵循 MVC 模式来尽可能地组织它。
我的结果保存在 .csv 文件中,因此目标应该是将它们“导入”到 GUI 中。我想使用“CTRL + O”作为快捷键打开这些文件,当然也可以使用菜单栏中的相应选项。
现在进入实际问题: 点击“CTRL + O”时调用的函数在控制器 class 中并且按预期工作,我可以打开一堆文件并且列表保存每个名称。但是当使用菜单栏时,我不知道如何实现“command=”选项。
这是我的代码:
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.constants import ANCHOR, TRUE
from tkinter import Label, filedialog
from tkinter import ttk
class Model():
# more to come
pass
class View:
def __init__(self, view):
self.view = view
self.view.title("analyzer")
self.view.geometry("640x480")
self.view.resizable(False, False)
# menubar
self.menubar = tk.Menu(self.view)
self.view.config(menu=self.menubar)
self.filemenu = tk.Menu(self.menubar, tearoff=False)
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label="Open", accelerator="Ctrl+O", command=Controller.get_open_filename())
self.filemenu.add_separator()
self.filemenu.add_command(label="Remove", accelerator="Ctrl+R")
self.filemenu.add_command(label="Information", accelerator="Ctrl+I")
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", accelerator="Ctrl+E", command=self.view.quit)
class Controller:
def __init__(self):
self.root = tk.Tk()
self.view = View(self.root)
# keybindings / shortcuts
self.root.bind_all("<Control-e>", lambda event: self.root.quit())
self.root.bind_all("<Control-o>", lambda event: self.get_open_filename())
self.list_of_files = []
def run(self):
self.root.mainloop()
def get_open_filename(self):
self.filename = askopenfilename(title="Select data file", filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
self.list_of_files.append(self.filename)
print(self.list_of_files)
if __name__ == "__main__":
c = Controller()
c.run()
如果有人能给我提示,我将不胜感激,希望我做错了。 谢谢!
您正在尝试从视图对象调用控制器函数,但视图不知道控制器具有该函数。它不知道控制器的存在。
可能有比这更好的方法,但您可以将函数作为参数传递给 View 的构造函数。
通过将 get_open_filename()
函数作为参数传递给 View 的构造函数,您可以将其用作命令。
注意:我调用了参数 func 这样您就可以看到我在做什么。不过我建议给它起一个更好的名字。
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter.constants import ANCHOR, TRUE
from tkinter import Label, filedialog
from tkinter import ttk
class Model():
# more to come
pass
class View:
def __init__(self, view, func):
self.view = view
self.view.title("analyzer")
self.view.geometry("640x480")
self.view.resizable(False, False)
# menubar
self.menubar = tk.Menu(self.view)
self.view.config(menu=self.menubar)
self.filemenu = tk.Menu(self.menubar, tearoff=False)
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label="Open", accelerator="Ctrl+O", command=func)
self.filemenu.add_separator()
self.filemenu.add_command(label="Remove", accelerator="Ctrl+R")
self.filemenu.add_command(label="Information", accelerator="Ctrl+I")
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", accelerator="Ctrl+E", command=self.view.quit)
class Controller:
def __init__(self):
self.root = tk.Tk()
self.view = View(self.root, lambda: self.get_open_filename())
# keybindings / shortcuts
self.root.bind_all("<Control-e>", lambda event: self.root.quit())
self.root.bind_all("<Control-o>", lambda event: self.get_open_filename())
self.list_of_files = []
def run(self):
self.root.mainloop()
def get_open_filename(self):
self.filename = askopenfilename(title="Select data file", filetypes=(("csv files", "*.csv"), ("all files", "*.*")))
self.list_of_files.append(self.filename)
print(self.list_of_files)
if __name__ == "__main__":
c = Controller()
c.run()