如何连贯地组织 PyGTK 桌面应用程序的模块?
我正在 PyGTK 中开发桌面应用程序,似乎遇到了文件组织的一些限制。 到目前为止,我已经这样构建了我的项目:
- application.py - 保存主要应用程序类(大多数功能例程)
- gui.py - 保存松散耦合的 GTK gui 实现。 处理信号回调等。
- command.py - 保存不依赖于应用程序类中的数据的命令行自动化功能。
- state.py - 保存状态数据持久化类
到目前为止,这已经服务得相当好,但此时 application.py 正在启动变得相当长。 我查看了许多其他 PyGTK 应用程序,它们似乎也有类似的结构问题。 在某个时刻,主模块开始变得很长,并且没有明显的方法可以在不牺牲清晰度和面向对象的情况下将代码分解为更窄的模块。
我曾考虑过将 GUI 作为主要模块,并为工具栏例程、菜单例程等提供单独的模块,但到那时我相信我将失去 OOP 的大部分好处,并最终得到一切引用一切的场景。
我应该只处理一个很长的中央模块,还是有更好的方法来构建项目,以便我不必如此依赖类浏览器?
编辑我
好的,关于所有 MVC 的内容就这样吧。 我的代码中确实有 MVC 的粗略近似,但不可否认,通过进一步分离模型和控制器,我可能会获得一些进展。 然而,我正在阅读 python-gtkmvc 的文档(顺便说一下,这是一个很棒的发现,感谢您引用它),我的印象是它不会解决我的问题,而只是形式化它。 我的应用程序是一个单一的林间空地文件,通常是一个窗口。 因此,无论我如何严格地定义模块的 MVC 角色,我仍然会让一个控制器模块完成大部分工作,这几乎就是我现在所拥有的。 诚然,我对正确的 MVC 实现有点模糊,我将继续研究,但在我看来,这个架构不会从我的主文件中获取更多内容,它只是重命名它文件到controller.py。
我是否应该考虑为窗口的不同部分(工具栏、菜单等)使用单独的控制器/视图对? 也许这就是我在这里所缺少的。 似乎这就是 S. Lott 在他的第二个要点中所指的内容。
感谢到目前为止的回复。
I am working on a desktop application in PyGTK and seem to be bumping up against some limitations of my file organization. Thus far I've structured my project this way:
- application.py - holds the primary application class (most functional routines)
- gui.py - holds a loosely coupled GTK gui implementation. Handles signal callbacks, etc.
- command.py - holds command line automation functions not dependent on data in the application class
- state.py - holds the state data persistence class
This has served fairly well so far, but at this point application.py is starting to get rather long. I have looked at numerous other PyGTK applications and they seem to have similar structural issues. At a certain point the primary module starts to get very long and there is not obvious way of breaking the code out into narrower modules without sacrificing clarity and object orientation.
I have considered making the GUI the primary module and having seperate modules for the toolbar routines, the menus routines, etc, but at that point I believe I will lose most of the benefits of OOP and end up with an everything-references-everything scenario.
Should I just deal with having a very long central module or is there a better way of structuring the project so that I don't have to rely on the class browser so much?
EDIT I
Ok, so point taken regarding all the MVC stuff. I do have a rough approximation of MVC in my code, but admittedly I could probably gain some mileage by further segregating the model and controller. However, I am reading over python-gtkmvc's documentation (which is a great find by the way, thank you for referencing it) and my impression is that its not going to solve my problem so much as just formalize it. My application is a single glade file, generally a single window. So no matter how tightly I define the MVC roles of the modules I'm still going to have one controller module doing most everything, which is pretty much what I have now. Admittedly I'm a little fuzzy on proper MVC implementation and I'm going to keep researching, but it doesn't look to me like this architecture is going to get any more stuff out of my main file, its just going to rename that file to controller.py.
Should I be thinking about separate Controller/View pairs for seperate sections of the window (the toolbar, the menus, etc)? Perhaps that is what I'm missing here. It seems that this is what S. Lott is referring to in his second bullet point.
Thanks for the responses so far.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在项目 Wader 中,我们使用 python gtkmvc,这使得在使用 pygtk 和 Glade 时应用 MVC 模式变得更加容易,您可以在 svn 存储库:
In the project Wader we use python gtkmvc, that makes much easier to apply the MVC patterns when using pygtk and glade, you can see the file organization of our project in the svn repository:
这可能与 PyGTK 无关,而是一般的代码组织问题。 您可能会从应用一些 MVC(模型-视图-控制器)设计模式中受益。 例如,请参阅设计模式。
This has likely nothing to do with PyGTK, but rather a general code organization issue. You would probably benefit from applying some MVC (Model-View-Controller) design patterns. See Design Patterns, for example.
“持有主要应用程序类(大多数功能例程)”
如单数形式——一个类?
对于一个类包揽一切的设计不起作用,我并不感到惊讶。 这可能不是我所说的面向对象。 如果您的功能堆积在单个类中,那么听起来它并不遵循典型的 MVC 设计模式。
这个庞大的班级里有什么? 我建议您可以将其重构为多个部分。 您有两个候选维度来重构您的应用程序类 - 如果我确实猜对了,您已将所有内容放入一个类中。
在做任何其他事情之前,请重构为与现实世界实体平行的组件。 目前尚不清楚“state.py”中的内容 - 这是现实世界实体的正确模型,还是只是持久存储与应用程序中某些模糊数据结构之间的映射。 您很可能会将处理从应用程序移出并转移到模型中(可能是 state.py,也可能是一个适合模型的新模块。)
将你的模型分解成碎片。 它将有助于组织控制和视图元素。 最常见的 MVC 错误是在控制中投入太多,而在模型中却没有投入任何内容。
稍后,一旦您的模型完成了大部分工作,您就可以考虑重构为与 GUI 演示并行的组件。 例如,各种顶级框架可能应该有单独的控制对象。 目前尚不清楚“GUI.py”中的内容 - 这可能是一个正确的视图。 似乎缺少的是控制组件。
"holds the primary application class (most functional routines)"
As in singular -- one class?
I'm not surprised that the One Class Does Everything design isn't working. It might not be what I'd call object-oriented. It doesn't sound like it follows the typical MVC design pattern if your functionality is piling up in a single class.
What's in this massive class? I suggest that you can probably refactor this into pieces. You have two candidate dimensions for refactoring your application class -- if, indeed, I've guessed right that you've put everything into a single class.
Before doing anything else, refactor into components that parallel the Real World Entities. It's not clear what's in your "state.py" -- wether this is a proper model of real-world entities, or just mappings between persistent storage and some murky data structure in the application. Most likely you'd move processing out of your application and into your model (possibly state.py, possibly a new module that is a proper model.)
Break your model into pieces. It will help organize the control and view elements. The most common MVC mistake is to put too much in control and nothing in the model.
Later, once your model is doing most of the work, you can look at refactor into components that parallel the GUI presentation. Various top-level frames, for example, should probably have separate cotrol objects. It's not clear what's in "GUI.py" -- this might be a proper view. What appears to be missing is a Control component.
抱歉这么晚才回复。 Kiwi 在我看来是比 gtkmvc 更好的解决方案。 这是我对任何 pygtk 项目的第一个依赖项。
Sorry to answer so late. Kiwi seems to me a far better solution than gtkmvc. It is my first dependency for any pygtk project.
Python 2.6 支持 显式相对导入,这使得使用包比以前的版本更容易。
我建议您考虑将应用程序分解为包内更小的模块。
您可以这样组织您的应用程序:
其中每个目录都有自己的
__init__.py
。 您可以查看任何 python 应用程序甚至标准库模块作为示例。Python 2.6 supports explicit relative imports, which make using packages even easier than previous versions.
I suggest you look into breaking your app into smaller modules inside a package.
You can organize your application like this:
Where each directory has its own
__init__.py
. You can have a look at any python app or even standard library modules for examples.因此,在没有收到关于我对原始问题的编辑的回复后,我做了更多的研究,我似乎得出的结论是是的,我应该将界面分成几个视图,每个视图有自己的控制器。 Python-gtkmvc 通过向 View 构造函数提供
glade_top_widget_name
参数来提供此功能。 这一切似乎都很有意义,尽管它需要对我现有的代码库进行大量重构,我可能愿意也可能不愿意在短期内进行(我知道,我知道,我应该。)此外,我想知道是否应该只有一个模型对象(我的应用程序相当简单——不超过二十五个状态变量),或者我是否应该将其分解为多个模型并必须处理观察多个模型并在它们之间链接通知的控制器。 (再次,我知道我真的应该做后者。)如果有人有任何进一步的见解,我仍然不觉得我已经得到了原始问题的答案,尽管我有一个现在前进的方向。(此外,鉴于到目前为止我还没有看到过以 MVC 风格编码的 Python 应用程序,因此它们似乎应该是其他架构选择,但许多 Python 应用程序往往会遇到我所描述的确切问题多于。)
So having not heard back regarding my edit to the original question, I have done some more research and the conclusion I seem to be coming to is that yes, I should break the interface out into several views, each with its own controller. Python-gtkmvc provides the ability to this by providing a
glade_top_widget_name
parameter to the View constructor. This all seems to make a good deal of sense although it is going to require a large refactoring of my existing codebase which I may or may not be willing to undertake in the near-term (I know, I know, I should.) Moreover, I'm left to wonder whether should just have a single Model object (my application is fairly simple--no more than twenty-five state vars) or if I should break it out into multiple models and have to deal with controllers observing multiple models and chaining notifications across them. (Again, I know I really should do the latter.) If anyone has any further insight, I still don't really feel like I've gotten an answer to the original question, although I have a direction to head in now.(Moreover it seems like their ought to be other architectural choices at hand, given that up until now I had not seen a single Python application coded in the MVC style, but then again many Python applications tend to have the exact problem I've described above.)