Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python MVC模式的重新分解——对视图与控制器分离的质疑_Python_User Interface_Model View Controller_Wxpython - Fatal编程技术网

Python MVC模式的重新分解——对视图与控制器分离的质疑

Python MVC模式的重新分解——对视图与控制器分离的质疑,python,user-interface,model-view-controller,wxpython,Python,User Interface,Model View Controller,Wxpython,我正在尝试将我的应用程序(包含1000多行GUI代码)重构为MVC风格的模式。 逻辑代码已经与GUI分离,因此这不是问题。我关心的是视图与控制器的分离。我理解MVC的基本原理,在wxpython wiki中非常有用,但是代码示例有点过于简单,当我尝试将该原理应用到我自己的项目时,我会产生疑问,因为我自己的项目比较复杂 结构的一个片段.. 我有一个main窗口,有许多小部件,包括一个笔记本(选项卡部分), 笔记本有许多选项卡其中一个选项卡(我称之为FilterTab)包含两个 类(我称之为Filt

我正在尝试将我的应用程序(包含1000多行GUI代码)重构为MVC风格的模式。 逻辑代码已经与GUI分离,因此这不是问题。我关心的是视图与控制器的分离。我理解MVC的基本原理,在wxpython wiki中非常有用,但是代码示例有点过于简单,当我尝试将该原理应用到我自己的项目时,我会产生疑问,因为我自己的项目比较复杂

结构的一个片段..

我有一个
main窗口
,有许多小部件,包括一个
笔记本
(选项卡部分), 笔记本有许多选项卡其中一个选项卡(我称之为
FilterTab
)包含两个 类(我称之为
FilterPanel
),它是一个带有列表框的面板,有三个按钮,一个用于清除,一个用于删除,另一个用于向列表中添加项目。取决于传递给 在实例化时初始化add buttons事件可以创建不同类型的对话框,例如文本输入对话框或directoryPicker等

这只是GUI的一部分,它是分层的,事件处理程序埋在FilterPanel类中

如果要将该部分转换为MVC,我必须为控制器(而不是FilterPanel类)中的每个FilterPanel实例绑定按钮事件——在这种情况下,有两个(FilterPanel实例)

因此,对于每个按钮(每个filterPanel 3个按钮*面板实例的数量)加上处理程序,我会有类似的东西

 self.mainWindow.filterTab.dirFilterPnl.Bind(wx.EVT_BUTTON,
                                    self.onAdd_dirFilterPnl, 
                            self.mainWindow.filterTab.dirFilterPnl.addBtn,
                            self.mainWindow.filterTab.dirFilterPnl.addBtn.GetId()
                                    )
这增加了大量额外的代码(如果我只有两个filterPanel实例,那么事件处理程序的数量将增加一倍)

所以我想知道我是否采取了正确的方法

如果我要把那个零件转换成MVC 我必须绑定按钮事件 对于FilterPanel的每个实例 在我的控制器中(而不是在 过滤板(类)

不一定!MVC的理念和实践并不意味着“视图”是基本的小部件;您的
FilterPanel
可以被认为/实现为一个“丰富/复合”小部件,它生成自己的、更高级别的“事件”(指向控制器)并进行适当更新。因此,这个复合小部件可以具有用于较低级别“事件”的处理程序,并从中合成较高级别的事件,将它们发送到控制器;控制器不必知道或关心每个按钮等,只需知道它接收到的更高抽象事件,如“用户想要为X目的选择目录”或“用户想要为Y目的输入文本”——并通过告诉视图该做什么来响应它们

关键的一点是,视图不会根据它处理的事件做出任何“语义”决策,也不会向模型发送任何命令——控制器是所有此类交互必不可少的“中间人”

一个类比,考虑GUI的最低层有非常低级别的事件,例如“鼠标左键下”和“鼠标左键”——一个“按钮小部件”通过改变按钮的外观(一个“视觉”决定而不是一个“战略”)直接对它们作出反应,并且最终,如果合适的话,合成一个更高的抽象事件,如“按钮被点击”(例如,当鼠标按钮按下后接着是鼠标按钮向上,而没有中间的鼠标移动使“点击”假设无效)。然后,后者被引导到需要“响应”按钮点击的更高层

类似地,rich/composite窗口小部件可以接收此类事件,并合成更高抽象度的事件,以便控制器做出反应。(相同的抽象事件可以通过按钮点击、菜单选择、某些击键生成……控制器不关心这些较低层的“视觉”因素,这是视图/小部件的工作,视图/小部件不硬编码用户交互的“战略”决策和动作,这是控制器的工作)

关注点的分离有助于解决测试和应用程序灵活性等问题;这不是闻所未闻的,这样的优势被购买的价格有一些更多的代码编写的替代品,所有的硬编码。。。但是如果你选择MVC,你就意味着这个价格对你来说是值得的


wx
可能不是实现这一点的理想框架,但您可以子类化——或者您可以使用一个单独的事件系统,如用于在单独子系统之间流动的更高抽象事件,以便将控制器与特定的GUI框架选择分离。我通常使用Qt,它的信号/插槽模型IMNSHO比典型GUI框架的事件系统扩展/扩展得更好。但是,这是一个不同的选择和问题。

wxPython包含了pubsub,它遵循发布/订阅方法。它类似于pydispatcher,尽管它们的实现不同。wxPython wiki提供了一些关于如何在程序中使用pubsub的示例,还有关于此主题的简单教程:

GUI中的MVC与Django或TurboGears中的MVC不太一样。我发现我可以将我的大部分逻辑放在控制器中,在我的“视图”中,我只绑定到控制器。大概是这样的:

view.py 绑定(wx.EVT_按钮,self.on按钮)

def ON按钮(自身、事件): controller.someMethod(*args,**kwargs)


根据计算内容的不同,我可能会从控制器运行一个线程,稍后使用wx.CallAfter+pubsub发布结果。

这是一个非常好的答案,它纠正了我的观点,即不健康地专注于从视图中删除所有事件绑定,这不仅不切实际,而且在根本上是不可能的。我以前开发过丰富的复合小部件,所以这不是问题(使用wx.NewEventType、wx.PyEventBinder、wx.PyCommandEvent来获取您建议的事件),w