wxPython评估笔记
最近写的一点笔记,留作备忘。
================================================================
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_Freeze,pyInstaller。这三种工具都有标准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真是飞速、稳定、可分发的开发环境,强烈推荐。
分类
Technology评论(5)
发表评论

大叔谈技术,青菜就发晕
原来你是干这个的啊。。。
你有专门的技术blog吗?很想看
我不写技术blog的
技术学起来太容易了,没啥技术含量
有内容的其实是行业经验,不过这个写出来没人要看的,太偏门了
这还不如骗小萝丽有技术含量
That's known that cash can make people autonomous. But how to act if one doesn't have cash? The one way only is to receive the mortgage loans or just credit loan.