当前位置: 首页 > 知识库问答 >
问题:

Python MWC模式GUI-控制器类的菜单栏命令

商华藏
2023-03-14

我正在尝试建立一个数据分析工具。我希望这种应用程序会越来越大,所以我将遵循MVC模式尽可能地组织它。

现在来看实际问题:当点击“CTRL O”时调用的函数在控制器类中,并且按照预期工作,我可以打开一堆文件,列表保存每个名称。但是在使用菜单栏时,我被如何实现“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()

如果有人能给我一个暗示,我会非常感激,我想我做错了。谢谢

共有1个答案

傅嘉悦
2023-03-14

您正试图从View Object调用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()
 类似资料:
  • 主要内容:实现,步骤 1,HomeView.java,StudentView.java,步骤 2,Dispatcher.java,步骤 3,FrontController.java,步骤 4,FrontControllerPatternDemo.java,步骤 5前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种设计

  • 前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种设计模式的实体。 前端控制器(Front Controller) - 处理应用程序所有类型请求的单个处理程序,应用程序可以是基于 web 的应用程序,也可以是基于桌面的

  • 前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种设计模式的实体。 前端控制器(Front Controller) - 处理应用程序所有类型请求的单个处理程序,应用程序可以是基于 web 的应用程序,也可以是基于桌面的

  • 顶部菜单栏中,设有文件、快捷代码、资源、工具、项目、视图和帮助控件,具体说明如下。 名称 说明 文件 可以控制新建项目、新建文件、保存和运行。文件支持.js、.css、.html和.json格式。 快捷代码 可直接将所需代码添加到所编辑的项目文件(光标所在位置)中。 资源 可打开工具栏中的相应面板,将提供的模型、园区、地图等资源加载到项目文件中。还可以查看并设置我的项目、我的园区和我的地图。参阅资

  • 左侧菜单栏包括图层、场景和底图。本章节中,我们将详细介绍菜单栏各功能的使用方法。 图层 图层的概念跟制图软件大致相同,可以理解为是堆叠在一起的透明纸。在 CityBuilder 中,通过图层可将数据文件加载到场景中,如城市建筑、道路、水系等。除了快速入门中介绍的加载公共数据以外,我们还可以上传本地的数据文件。 按下列步骤,将我的数据加载到图层中,并设置图层属性。 在左侧菜单栏中,点击图层右侧添加图

  • CampusBuilder 场景编辑器的顶部菜单栏设有7个基本功能项,包括文件、编辑、选择、工具、视角、插件和帮助。 文件 顶部菜单栏的文件控件包含以下功能: 可以打开本地 3D 场景文件; 将文件保存/另存为,在我的场景中可以看到保存后的场景,最后保存时的窗口图将作为场景的封面; 导入模型文件,支持的文件格式包括 .fbx, .obj, .3ds, .stl, .dae, .3d, .3mf 等