其实,PyQt的实际使用经验,我大概也就三个月。而Qt,最多也就一个月吧。所以这篇文章并不是想说Qt的编程和PyQt的编程。而是想说说我这一个多礼拜的编译经验和这两者的关系而已。(只涉及技术思路,不涉及具体技术。具体技术网上一大堆。)
Qt,最大的好处是可移植。Python,最大的好处是编程更加敏捷,且也是可移植的。那PyQt,其实就是Qt的一个Python wrapper。现在好多C/C++的动态库都有Python的wapper。比如我常常使用的OpenCV啦,还有同事经常使用的OpenGL啦,OpenCL啦。所以目前,用C++进行底层的实现,而提供Python的接口,是比较流行的做法。女儿前段时间很喜欢看《海底小纵队》,我也跟着看了几集。里面有一个叫巴克的北极熊和一个叫呱唧的猫。他俩经常一起出去执行任务,因为组合了北极熊的力量和猫的敏捷,他俩总是能出色地完成各种考验。现在想想,如果把C++比喻成北极熊,而把Python比喻成猫,也是十分合适的。
说回Qt/PyQt的编译。现在常用的Qt版本有Qt4和Qt5两种。目前来说还是支持Qt4的开源库多一些。而Qt4相较于Qt5,我暂时还没有感受到明显的弱项。所以我电脑上的环境目前是Qt4的最高版本-4.8.11。如果是安装Qt,在Ubuntu上可以直接用sudo apt install
来安装Qt的开发库。在Windows上有相应的安装程序来安装。那PyQt呢,得看你用什么python版本。有的python版本,用pip就可以直接安装,而又的python版本,就是无法直接安装。而好死不死,由于某种原因,我必须使用的python版本,用pip就是无法安装PyQt4。这个时候就要通过源码来编译。
上riverbankcomputing的网站,上面有下PyQt4,PyQt5以及SIP的源码。SIP,是编译PyQt所必须使用的编译工具。所以编译PyQt的顺序是这样:
- 安装好Qt。
- 保证qmake在Windows的控制台或Ubuntu的终端上是可用的。
- 下载SIP源码包,安装SIP。
- 下载PyQt源码包,安装。
这里比较好玩的地方在于,看看Qt到PyQt到底是怎么做的。PyQt的源码包中没有Qt的任何原文件,只有一些sip定义的文件,还有其它的一些工具软件。也就是说,PyQt的具体实现,真的就是在Qt中。另外,在整个编译过程中,并不需要对Qt本身进行修改。那SIP的做法很好啊~后来,我看了一下SIP的文档。在Introduction中,是这么说的:
SIP是一个工具,能对C/C++库自动生成Python-bindings。SIP最初是在1998年被开发出来用于PyQt——the Python bindings for the Qt GUI toolkit,但是它也同样适用于C/C++库。
本版SIP生成的绑定适用于Python2.3及以后版本,包括Python3。
还有许多跟SIP功能类似的工具。其中一个就是SWIG,事实上SIP之所以被叫做SIP是起初就是一个小的SWIG。与SWIG不同的是,SIP是专门设计用于将Python和C/C++集成在一起,并不遗余力地使集成更加紧密。
其特点如下(不全,摘录):
- 绑定能够被快速加载,并且最大限度地减少了内存消耗,特别是在仅使用大型库的小型子集时
- 标准Python和C/C++数据类型之间的自动转换
- 用不同的参数签名重载函数和方法
- 支持Python的关键字参数语法
- 支持明确指定的和自动生成的文档注释
- 能够访问C++类的protected方法
- 能够定义一个Python类,它是C++类的一个子类,包括抽象的C++类
- Python子类可以实现__dtor __()方法,该方法将从C++类的虚拟析构函数中调用
- 支持普通的C++函数,类方法,静态类方法,虚拟类方法和抽象类方法
- 能够在Python中重新实现C++的虚拟方法和抽象方法
- 支持全局变量和类变量
- 支持全局操作符和类操作符
- 支持C++命名空间
- 支持C++模版
- 支持C++异常并以Python异常的方式捕获它们
- 支持弃用警告
- 能够定义C++类与相似的Python数据类型之间的映射,并且是被自动调用的
- 能够自动利用任何可用的运行时类型信息来确保Python实例对象的类匹配相应C ++实例的类
- 能够改变Python对象的类型及元类型,用来包装C/C++的数据类型
- 全面支持Python全局解释器锁定,能够让指定的C++函数阻塞,允许释放锁定从而运行其他Python线程
- 支持C++实例所有权的概念(例如,代码的哪一部分负责调用实例的析构函数)以及在应用执行期间所有权可能如何改变
- 能够生成一个C++类库的绑定,这个C++类库是在另外一个已经生成了绑定的C++类库的基础上建立的,因此不同的绑定能够集成和并正确地共享代码
- 有一个复杂的版本控制系统,从而允许在一组简单的规范文件中描述C++类库的完整生命周期,包括任何平台特有的或者可选的特征。
- SIP 可以在 UNIX, Linux, Windows, MacOS/X, Android and iOS下使用。
另外,看了一下Using SIP的文档。其中比较复杂的那个例子,说明了如何使用Qt来编写一个控件,然后把它放到PyQt的工程中。这么做是非常有意义的。因为:
- 如果控件本身的逻辑比较复杂,用Python实现比较慢,那就可以用C++来实现,只在PyQt中调用即可。
- 万一看到别人用C++的Qt实现了一个自己想用的控件,可以在几乎不改人家的源代码的情况下,拿过来嵌入到自己的PyQt项目中。(不过有一个前提,人家用Qt4,你就得用PyQt4,人家用Qt5,你就得用PyQt5)
注:官网提供了Qt4到PyQt4的例程,github上有一个Qt5到PyQt5的例程。在Google搜索Qt5ToPyQt5即可。