这几天用pygtk和glade写了一个不大的应用,在ubuntu下开发,然后移植到Maemo平台。
学习的过程中发现了SimpleGladeApp.py这个module,可以更方便地以面向对象的方式使用libgrade。
还记得serverinfo这个例子吗?里面是这样得到一个widget的实例的:
- self.wTree = gtk.glade.XML(self.gladefile, self.windowname)
- self.logwindowview = self.wTree.get_widget("textview1")
用了SimpleGladeApp.py,直接用self.logwindowview就行了。
下面是改造serverinfo使用SimpleGladeApp.py的步骤:
1. 从 http://www.gnomefiles.org/app.php/SimpleGladeApp.py 下载SimpleGladeApp.py
2. 解压缩后把tepache这个脚本放到你的PATH环境变量指定的路径下,比如/usr/local/bin,然后加上执行权限。
3. 我们已经有现成的serverinfo.glade文件了,现在要做的是用tepache这个脚本解析glade文件来生成一个Python模块,里面是一些对应window或dialog等顶层widget的class,并实现他们的callback方法。命令如下(-o选项是为了不覆盖原来的serverinfo.py):
$ tepache serverinfo.glade -o serverinfo_new.py
written file serverinfo_new.py
$ ls
serverinfo.glade serverinfo_new.py serverinfo.py
serverinfo.gladep serverinfo_new.py.orig SimpleGladeApp.py
可以看到tepache生成了三个文件:serverinfo_new.py, serverinfo_new.py.orig, SimpleGladeApp.py
.orig文件很重要,tepache用这个文件保护你在serverinfo_new.py添加的代码,所以不要删除这个文件。
可以先运行serverinfo_new.py看看效果。
4. serverinfo_new.py的部分代码:
- ......
- # Warning: Do not modify any context comment such as #--
- # They are required to keep user's code
- ......
- from SimpleGladeApp import SimpleGladeApp
- from SimpleGladeApp import bindtextdomain
-
- app_name = "serverinfo"
- app_version = "0.0.1"
-
- glade_dir = ""
- locale_dir = ""
-
- bindtextdomain(app_name, locale_dir)
-
- class Serverinfo(SimpleGladeApp):
-
- def __init__(self, path="serverinfo.glade",
- root="serverinfo",
- domain=app_name, **kwargs):
- path = os.path.join(glade_dir, path)
- SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
-
- #-- Serverinfo.new {
- def new(self):
- print "A new %s has been created" % self.__class__.__name__
- #-- Serverinfo.new }
-
- #-- Serverinfo custom methods {
- # Write your own methods here
- #-- Serverinfo custom methods }
-
- #-- Serverinfo.on_serverinfo_destroy {
- def on_serverinfo_destroy(self, widget, *args):
- print "on_serverinfo_destroy called with self.%s" % widget.get_name()
- #-- Serverinfo.on_serverinfo_destroy }
- ......
- #-- main {
-
- def main():
- serverinfo = Serverinfo()
- demodialog = Demodialog()
-
- serverinfo.run()
-
- if __name__ == "__main__":
- main()
-
- #-- main }
5. 现在就可以添加一些代码来实现serverinfo的功能了。注意不要修改形如#– Demodialog custom methods { 这样的注释,否则如果界面(glade文件)有了改动,tepache就没法做patch了。
把原来的insert_row改成ServerInfo类的一个方法,放在#– Serverinfo custom methods 注释之间。
goUrl方法也放在这里。 注意访问widget实例的方法已经由
host = self.wTree.get_widget("entry1").get_text()
变成
host = self.entry1.get_text()
main方法里的实例化Demodialog的语句要挪到button2的clicked事件响应方法里,不然程序一运行对话框就出现了,你刚才一定注意到了。
destroy响应方法里加入self.gtk_main_quit()以便窗口销毁时能够退出程序。
6. 现在运行serverinfo_new.py,原来serverinfo.py的功能基本上都有了。但有一个问题,对话框弹出后点击“确定”或“取消”按钮都不能关闭对话框。我的解决办法是不在glade设计这个对话框,完成在程序里用代码实现。
7. 注意每次重新设计了界面,修改了glade文件,都要运行tepache来patch生成的python模块,已做的修改不会被覆盖。
新的代码下载地址: http://guoyong.org/?dl=pygtk-learning-serverinfo-simplegladeapp.tar.bz2