Python MWC模式GUI-来自控制器类的Menubar命令



我正在尝试构建一个用于数据分析的工具。我预计这种应用程序会变得很大,所以我遵循MVC模式来尽可能地组织它。

我的结果保存在.csv文件中,所以目标应该是"导入";将它们输入GUI。我想用"打开"打开这些文件;CTRL+O";作为keybinding,当然也可以使用菜单栏中的相应选项。

现在来谈谈实际问题:当点击";CTRL+O";在Controller类中,并按预期工作,我可以打开一堆文件,列表保存每个名称。但当使用菜单栏时,我被如何实现";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对象调用Controller函数,但View不知道Controller具有该函数。它不知道控制器的存在。

可能有比这更好的方法,但您可以将函数作为参数传递给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()

最新更新