编写Python GTK+应用的“好实践”方式是什么?
我现在正在写一个PyGTK应用程序,想请教一下如何更好地组织我的应用程序。简单来说,这个应用程序会读取一个特定格式的文件,并在图形界面中展示出来以供编辑。
目前我有一个parser.py文件,负责处理所有的文件输入输出和解析工作。我把文件的内容显示在一个树形视图中,这就意味着我需要使用一个树存储(treestore)作为我的数据类型。
我遇到的问题是,我只想到两种解决方案。第一种是让我的解析器构建一个树存储,然后把它传给我的用户界面类。这就要求我的解析器依赖于pygtk,这样会减少这个类的重用潜力。第二种方案是把我的用户界面类的引用存储在解析器中,这样也可能限制我的解析器作为独立库的重用。
简单来说,我想问的是:有没有更符合Python风格或者面向对象的方式来实现我的目标?
如果有人想看我的代码来帮助回答我的问题,可以访问这个链接:https://code.launchpad.net/~blainepace/nbtparser/trunk
欢迎其他Python方面的建议,这是我写的第一个Python程序,我可能还停留在更像C++的思维方式上。我计划对很多部分进行重构。
1 个回答
你可以看看这个教程 “在Python中子类化GObject”。这个教程讲的是如何使用GObject的类型系统来创建信号和属性,这样可以让你更容易地模拟底层行为,并且与PyGTK的常规用法(比如连接信号、等待属性通知等)很好地结合起来。
你的解析器和用户界面应该只包含属性和信号可以连接。然后,你可以再创建一个第三个类,用来连接这些信号和回调,并在一个 if __name__ == __main__
的代码块中启动主循环。
通常,我的代码看起来像这样:
class MyApp(gtk.Window):
def __init__(self, parser, ui):
gtk.Window.__init__(self)
parser.connect("some-signal", ui.update_this)
parser.connect("some-other-signal", ui.update_that, extra_params)
ui.connect("refresh-clicked", parser.reparse_file)
self.add(ui)
...然后在你的主脚本中:
parser = parser.Parser(...)
ui = view.ParseView(...)
app = MyApp(parser, ui)
app.show_all()
gtk.main()
当然,这通常会根据不同的情况而有所不同,比如我是否在使用Glade?我是在为主应用程序子类化小部件,还是在包装它们?等等。
这其中最棒的地方是,你可以写一个测试解析器,它只返回预设的响应,或者使用一个已知的测试文件。只需更改上面的一行代码,就可以轻松替换它:
parser = parser.DummyParser(...)