glade+pygtk 试用札记


               
   由于用python写程序,我已经考察过了好几种python的界面编写包,默认的tcl/tk,wxWindow,近来又试用pygtk。感觉用
pygtk是最顺手的,大约是因为我不熟悉c++而更熟悉c和callback吧。在加上glade编辑界面非常迅速方便,我更喜欢这个python+
pygtk+glade的组合了。
   gtk的大名相信不用我多介绍,gnome就是用它开发的,pygtk是gtk的python接口封装(反正就是在python中调用gtk,具体名称是
什么我也没弄清楚)。glade是gtk的界面编辑工具,不象我们在win下熟悉的vb,c++builder等IDE,glade只管生产界面和产生相
关的代码,至于编译和代码编写,你还需要vim,gcc等其它工具。glade生成的是.glade文件,内容是xml,描述了界面的控件和布局;配合特
定的代码生产器,它可以产生出对应各种语言的原代码,我所装的window版本有devc++和vc的生产器,我试了一下devc++的,glade产生
的工程和代码可以马上编译运行,得到的界面和glade中的设计分毫不差。我也找到了for
python的代码生成器,但是相比之下我更喜欢用glade文件动态生产界面,也就是不产生直接定义控件的python或c代码,而是用
libglade在程序启动时读取.glade文件生产界面。
   在使用pygtk一前我做了很多搜索,我搜索到的文章似乎都比较旧,介绍的pygtk for
win32的方法现在已经都不适用了,他们给了我很多警告,需要下载很多各种文件,但我自己安装时却什么困难都没有遇到,直接的下载了gtk-win32
-devel-2.8.6-rc3,pygtk-2.8.2-1.win32-py2.4安装后重启就可以了(虽然它没有警告你,gtk-win32安装
后一定要重启,一些注册表项才能起作用,如果不重启,写出的程序会说某个函数在dll中找不着,我开始以为是bug,折腾了个把小时,由于死机才算搞懂
了:-()。
   好了下面开始介绍glade和pygtk的使用。
   gtk-win32-devl-2.8.4-rc3已经包含了glade,gtk,libgalde等几个工具和库文件。安装后glade马上就能使用,
但库的调用却要求必须重启。使用glade作界面是比较简单的(我也只使用了一些简单的功能,table我都没有用到。)glade的控制可以分为两类:
box是用来调整布局的,有hbox和vbox两中,h和v就是水平和垂直的意思;box是不可见的,真正的控件如按钮和输入筐等就放在box上面,也就
是说box负责分割窗口,其它控件负责交互。一个窗口总是先被其中一种布局的box分割成几行(或列),然后再在一个行(或列)中细分。box的属性窗中
有个size项,代表的就是你把窗口或上一级的box分成了几份,如果开始时分少了可以修改这个值,多分出几份来,反之也可以减少几份。一个非box的控
件必须占据一个box,所以你可以规划如何用box分割窗口,按层次关系把控件拉进box中。由于在只有box时无法调整box的大小(他们总是平分上一
级的box),所以你必须想好先要水平还是垂直的分割窗口;做了一次分割后就把不需要在细分的box的控件放进去,然后再来做余下的分割。在使用
glade时最好把widget tree窗口也调出,点击box的一个格时,是不能选中box的,必须在widget
tree中选中box才行,我发现combobox控件也有这个问题。用hbox分割vbox的一格时,控件会拉得很高,这时可以把hbox的
Expand和Fill属性设成No,控件就会缩回到他们应有的高度。properties窗口可以设定各个控件需要响应的信号,设定回调函数,也就是
delphi中的事件响应函数,如按钮的点解事件,窗口的关闭事件等。glade的使用是比较直观和简单的,用过delphi和vc的人估计都能马上明白
如何使用。做好界面布局后保存工程,.glade文件就会生成,使用build项就会产生对应的c代码。
   虽然我装的glade没有for
python的代码生成器,但我们有更简单的方案--libglade,通过.glade文件动态生成代码。在我搜到的文章中,介绍的的libglade
是要单独的import进来的,但新的pygtk似乎已经集成了libglade, import gtk后可以用以下的一句话调出界面:
    self.comWin=gtk.glade.XML("pycom.glade","mainWin")
在这里pycom.glade是我的glade生成的界面描述文件,mainWin就是窗口的名字,由于一个glade文件可以包含了多个窗口的描述,所
以你需要指定是调出那个窗口。然后,我们可以马上把回调信号和你的python函数用signal_autoconnect链接起来:
    self.comWin.signal_autoconnect(self.signals_dict)
signal_dict是信号和pythong函数的对应字典:
#    signals_dict={
#    "on_openButton_clicked":btOpenClick,
#    "on_sentButton_clicked":btSentClick,
#    "on_sentFileButton_clicked":btSentFileClick
#    }
   用这个办法可以用最小的代码初始化程序,但它有一个坏处(也可能是我还没有弄懂),pythong函数不能把self对象传递进函数中,传递进来的只有发
生信号的控件指针。所以我没有用asignal_autoconnent函数,而是把控件逐一取出,把信号和响应函数链接起来:
    button=self.comWin.get_widget("sentButton")
    button.connect("clicked",self.btSentClick  
btSentClick定义如下(如果用signal_autoconnet则不能有self参数,对象指针就传不进函数中,处理起来很麻烦,希望有高手来说说有没有更好的办法。):
    def btSentClick(self,widget)
   程序中我还试用了gtk的idel函数和定时处理函数,前者在空闲时被调用,后者则每隔一定时间被执行一次,我用他们来做串口的接收。虽然我也写了另一个
线程做接收,但为简化程序而没有用上,线程代码虽然能用,但是有bug的,会出错,而空闲函数对低速的串口也能很好的响应。
   总之pygtk+glade给我的感觉是个不错的开发界面的组合,而且开发出来的界面还可以被其它语言使用,在加上gtk包的广泛应应用,使用这个组合是个很不错的选择。
   下面是window下的pygtk和glade的下载地址,我的程序的文件和代码在资源中心的pycom.rar中。
http://www.pygtk.org
http://www.pcpm.ucl.ac.be/~gustin/win32_ports/
http://gladewin32.sourceforge.net/modules/news/