wxPython评估笔记

来源:http://mach.debagua.com/archives/2009/0706_001023.html

wxPython(1)wxWidgets

新开张的一个项目需要同时支持Windows和Linux的图形界面,以及内里对复杂XML的处理。又需要去寻找solution了。XML的处理简单,交给Perl去做,Perl的hash结构和simple xml模块足够快速打败这个任务。而且Perl程序也可以很方便地打包(linux上用pp,Windows上用ActivePerl)成可移植二进制包。而GUI的跨平台设计,简单的考虑,有三个可能方向:

QT - 在Linux可用QT Designer,WYSIWYG的设计界面很方便。Windows上不详。但是QT的license对商业应用有限制 
Java - 人人都知道它跨平台,我们之前开发GUI也都一向用控件集合SWT+文档视图类JFace,不过这玩意的开发效率和运行效率都真的不咋地 
wxWidgets - 最近几年比较热门的一个C++图形库,本质上用本地控件,在不同平台上效果会和本地主题一致,图形库在Linux上是基于GTK的,Windows上基于Windows Platform SDK。形式上它和MFC框架很像,用过MFC的人多半都能很快进入状况。

我以前MFC玩得多了,Qt和Java也都有所了解也都不太满意,那么首先拿wxWidgets体验下,需要关注的是安装、快速开发、打包

Windows安装

首先需要一个本地C++编译器。当然可以装MinGW之类的编译器,我懒得搞了,装了个Visual Studio.NET 2003,比较老的版本了。其实微软网站上现在Visual Studio.NET C++ 2008 express是免费下载的,但我不确定那个免费的包里头有没有Wind32 Platform SDK,也许需要另外装SDK。总之装好之后把nmake所在目录加到Windows系路径,把Platform SDK目录加到系统库路径后面就方便了。

然后下载wxWidgets安装。下载的其实是源代码2.8.9版本,需要编译成本地*.o文件,这个还满费时间的。具体编译过程看readme就好,需要注意的是要选择语言格式和后台图形库支持,我选的是UNICODE和gtk2。建议选这两个,因为是主流。

现在就可以用了。找几个例子程序(源代码包里面有的)来编译下,如果有问题,多半都是因为库的路径等原因,稍微调整一下就好。

Linux安装

这个就方便了,现成用g++编译。同样要注意选UNICODE编译选项。

快速开发

很多geek是看不上快速开发工具滴。。。我也同意快速开发工具(RAD tool)并不是那么重要,因为很多稍微复杂一点的界面操作都是快速开发工具做不了的,还是得写代码。但是当你对一个库里头有些什么控件都没概念的时候,一个好的快速开发环境能让你省很多翻书翻手册的时间。很不幸,我试验过了wxDev-C++和wxGlade,前者在我机器上极端不稳定,后者只支持sizer方式定位控件。

Java比较熟悉的同志可以把wxWidgets的sizer类类比成Java的container类,对于只玩过MFC的同志们可能有点陌生。简单说,以前Visual Studio里头,把一个控件拉到dialog后,生成的代码或者资源文件里控件的位置和大小是用(x,y)绝对值来表示的;这个思维很直接,不需要解释。wxWidgets觉得这样不好,当整个窗口被拉大的时候,控件就全挤左上角了,不好看,所以发明了sizer类动态管理控件的位置。wxWidgets中有很多sizer类,sizer类可以套sizer类或者控件。很像那个装在盒子里的人。。。不过,写HTML写得多的人(这个,很多人折腾过自己blog的模板吧)应该能理解,HTML里面定位不就是用表格和frame嵌套的方式套来套去达到在不同的分辨率下都可以看么,就是太麻烦了。--当然wxWidgets还是支持绝对定位方法的,找不到快速

打包

我没找到合适的打包工具,虽然说编译的是本地可执行代码,可是我得手工把一些wxWidgets的库拉出来才能脱离开发环境运行。麻烦。。。

考虑到用C++开发还需要处理异常,忒麻烦,退缩了,想其它办法去

 

资料

网上很容易找到《Cross-Platform GUI Programming with wxWidgets》和它的中文版本《使用wxWidgets进行跨平台程序开发.pdf》,看起来用它的人还真不少。这本书再加wxWidgets自带的帮助和例子程序,基本上就够用了。

 

================================================================

wxPython(2)Python

前文说到,直接用wxWidgets还是很麻烦的,调查了一下,基于wxWidgets,有很多wrapper,例如wxPerl, wxPython, wxRuby,分别是用Perl/Python/Ruby来包装C++的wxWidgets。先去调查了一下wxPerl,开发度很差,人气很比较差,现在基本是停滞状态。wxRuby是新事物,人气满旺但开发度不够。wxPython大家都认为已经做得不错了。到SourceForge上搜了一圈,发现Linux上的某BT软件,还有我以前用过的本地blog编辑工具zoundry,都是用wxPython做的,这两个用户量都不小。另外,Zoundry现在开源了,用CVS软件(在windows上可以用TortoiseCVS,Linux自带svn)下载了源代码运行起来,界面很酷。

那么先花几个小时学一下Python。这个脚本语言的语法和支持对象的VB有点像,习惯了C++/Java/Perl这种“类C”语言的人难免刚开始有点皱眉头,但是其实习惯了它的逻辑就好:例如说用空白正确缩进在Python里很重要,重要到了关系程序能不能正确和正常运行的程度;例如说它的函数没有明显的结尾,没有花括号结尾也没有return也可以;变量名没法像perl的use strict一样强制预先定义。

因为要处理XML,考察了一下Python的XML处理。像我这样被perl庞大而且强大的开发者代码共享社区的CPAN宠坏了的人发现Python没有一个好用的开发者社区的时候还是满震惊的。花了不少时间在搜索引擎上才明白ActiveCode上Python的代码比较多,但是也是在找了几个版本之后才找到一个好用的,和Perl的XML::Simple用法相当的XML2Obj模块。

用XML2Obj读的XML文件到内存以后,是一个嵌套的dictionary,这种结构相当于Perl的hash, 但是,真难用啊,居然没有Data::Dumper模块可以把这个dictionary给打印出来,还得在XML2Obj里面写一个xmlTree2String( )函数。

有一本叫《A byte of Python》的书,里面有一节叫“Why not Perl?” ,是打击Perl的,理由是用perl开发大型程序很困难--这个人明显没有好好用Perl的面向对象特性的,我们做的Perl程序都相当复杂了,照样组织得好好的。但就是他,也不得不承认Perl的CPAN社区太强大了,希望能够把Perl的模块转到Python上。我很奇怪为啥没有人来组织一个类似的社区网站。

最后,基本上我觉得学计算机语言没啥好说的,看看语法,安装开发环境跑几个例子就好。Python的电子书很容易找到,在这个网站www.pythonid.com里面直接能下载到很多,我就是花了几个小时随便看了两三本,发现网上有人比我还激进,号称十分钟可以学会Python,:-)

参考链接

华蟒用户新闻组 http://groups.google.com/group/python-cn

Python news group http://groups.google.com/group/python

以上两个新闻组的地址是用来搜索的,要发言还得设置outlook express用NNTP协议连新闻服务器。

 

================================================================

wxPython(3)wxPython

对Python语法和面向对象方式稍有了解就可以来玩wxPython了。下载wxPython安装。我在Windows上下载的是runtime binaries, 在Windows XP上安装运行没有任何问题。但是在Linux上只有源代码可以选择,编译的时候出问题了(我的wxWidgets版本是2.8.9),某个类缺少一个 CreateBitmap()方法。看了一下,似乎只是一个wrap而已,自己加一个空的CreateBitmap()就好?搜索一下,果然有人给出了patch,和我想的一样。

Python下使用wxWidgets编程,不二的教程就是《wxPython in Action》,虽然这本书已经有了中文版,但是500多页16开读起来也不是那么容易的,我的办法是直接运行和阅读源代码,可以急速读完:D

使用wxPython的开源项目很多,用wxPython做关键词在google code或者sourceforge上一搜一大把项目,其实我前面推荐的zoundry是很复杂的项目,推荐一个litebook,比较简单易学。另外,豆瓣网是全用python开发的,而网上能搜到的一些豆瓣插件也往往是用python写的,例如“豆瓣好友跟踪”,也有源代码可以参考。

下面说说wxPython的快速开发工具了。wxPython的界面有两种写法,一种是用自带的XRCeditor,创建一个叫XRC的XML文件,界面和控件都写成XML格式固化。因为我的软件的界面会有动态元素,所以跳过这种先进方式,直接寻找用源代码创建控件的方法。

搜来搜去,发现大家都在提一个叫BOA的工具。当下Windows版,安装,然后,呃,开始菜单里什么都没有增加呀?想了下,BOA自己称自己也是基于wxPython的,那么全硬盘搜索下"boa.py”,果然在python的site packages里面找到了,直接python boa.py,一个类似于以前Delphi开发环境的GUI就出来了。

前面说过wxWidgets的布局是用一个叫sizer的类,我不用搞那么复杂,直接按绝对像素布置控件就好。那么就简单了,在BOA里创建一个frame, frame上创建几个panel, 把控件放在不同的panel里想要的位置,然后点那个对勾图标,代码就生成好了。直接运行,想要的窗口就出来了。BOA还支持消息映射,可以在GUI里添加消息映射和消息处理函数。

结论:Python+wxWidgets+BOA 非常好用!

 

================================================================

wxPython(4)distribution

基于wxPython的软件做好,一定要打包的,你没法保证目标机器上的运行环境和本机一致。

打包Python程序有很多种选择,在Windows上很简单,用py2exe。只要写一个setup.py, 然后使用python的标准分发接口disutilis的标准用法

python setup.py py2exe

如果setup写得不对会生成很多文件,希望出来的结果干净一点,setup.py要这样写,设置bundle_files

from distutils.core import setup  
import py2exe  
includes = ["encodings", "encodings.*"]  
options = {"py2exe":  
            {   "compressed": 1,  
                "optimize": 2,  
                "includes": includes,  
                "bundle_files": 1  
            }  
          }  
setup(     
    version = "0.1.0",  
    description = "radargraph",  
    name = "radargraph",  
    options = options,  
    zipfile=None,  
    windows=[{"script": "myApp.py", "icon_resources": [(1, "myApp.ico")] }],    
    )

其中myApp.py和myApp.ico要改成自己的文件。做出来的有一个win32可执行程序,一个vc7的dll,两个文件而已,很干净。大小大约在4M到10M之间。

在Mac上据说py2App的表现和py2exe一样方便,我没有Mac系统没法试验。

在Linux上有点麻烦,我试验了Python自带的freeze.pl,以及cx_FreezepyInstaller。这三种工具都有标准python disutils接口,使用方法都一样,写一个setup.pl文件(当然不同的工具对这个的格式要求可能不一样,详细见各个工具的手册和例子),然后运行python setup.pl xxx (这里xxx是各工具的名字)。

试验结果如下,pyInstaller, 打包失败,原因不详,也许是我setup.pl写得不好?但我看了又看,没看出问题,然后发现它网站上的例子我也编译不成功,没耐心了。freeze.pl打包成功,但是拷到其它Linux机器上运行失败,因为库文件没有拷全。我估计自己手工把python和wxWidgets的*.so文件拷过来应该可以,但是查找dependency很麻烦啊。cx_Freeze是最后一棵稻草。运行下来,嘿嘿,所有*.so都拷全了,虽然有些不必要的gcc的*.so它也拷过来了。最后做出来的是一个可执行文件和十多个so文件,其中libwx_gtk2ud_core-2.8.so.0文件就有20M。这个tar.gz之后还有20多M。。。确实能够工作,可是尺寸太大了!我们想要的是一个能够通过email发给客户的版本,这个太巨。

-----------另外,关于wxPython用到的资源文件----------

用BOA来在界面上创建Bitmap图标或者bitmap时,生成的代码是直接调用bitmap文件。这样子生成的可执行文件,在目标机器上可能会找不到资源。解决方法是参考《wxPython in Action》的第二章的例子代码,里面有个images.py,是由Python的XRCeditor里面的encode_bitmaps.py生成的资源文件。打开encode_bitmaps.py看一下就明白应该怎么做,会生成一个python文件,里面有若干PyEmbeddedImage对象(和第二章的例子有点不一样了)。例如

Image_title = PyEmbeddedImage( 
    "iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAAA3NCSVQICAjb4U/gAAAek0lE" 
)

要用的时候就在需要BITMAP的地方Image_title.GetBitmap()就好了。缺点是这样改之后,BOA就不能load这个项目了,因为BOA不认PyEmbeddedImage。

----------------------------------------------------------

继续寻找新方法。大家都知道,连接Python和C/C++库的桥梁有: 
1. 直接使用Python提供的C API - 这个很麻烦 
2. SWIG 其实SWIG不只支持Python, 它功能很强大,很多脚本语言都用它和C接口。当年wxPython开发时1.0版本用方法1,后来没法维护了,最后只好改成SWIG。缺点是很繁琐。 
3. Boost.Python 据说用这个接口C++很方便 
4. Pyrex 

pyrex,是一种新的脚本语言。它用类似于Python的语言来写代码,然后用pyrex工具变成C代码,最后编译成可执行程序。同时pyrex代码中可以使用和调用Python代码。于是有些人就利用这个方式来通过pyrex把python变成C,再编译成可执行代码。David McNab有一个关于如何做的教程,我试验过了,简单的Python程序可以;但是对于wxPython程序,转出来的C文件编译不成功,看起来对于wxWidgets的支持有问题。

参考

牡蛎的如何编译Python程序 
Pyrex, 和Python的C扩展

------------------------------------------------------------

最后这个项目可耻地还是用了Java SWT+Jface。原因就是20M的可执行包太大了。其实,对于没有这种限制的项目,wxPython+BOA+cx_Freeze真是飞速、稳定、可分发的开发环境,强烈推荐。

你可能感兴趣的:(linux,python,perl,qt,wxPython)