
其實(shí),PyQt的實(shí)際使用經(jīng)驗(yàn),我大概也就三個(gè)月。而Qt,最多也就一個(gè)月吧。所以這篇文章并不是想說Qt的編程和PyQt的編程。而是想說說我這一個(gè)多禮拜的編譯經(jīng)驗(yàn)和這兩者的關(guān)系而已。(只涉及技術(shù)思路,不涉及具體技術(shù)。具體技術(shù)網(wǎng)上一大堆。)
Qt,最大的好處是可移植。Python,最大的好處是編程更加敏捷,且也是可移植的。那PyQt,其實(shí)就是Qt的一個(gè)Python wrapper?,F(xiàn)在好多C/C++的動態(tài)庫都有Python的wapper。比如我常常使用的OpenCV啦,還有同事經(jīng)常使用的OpenGL啦,OpenCL啦。所以目前,用C++進(jìn)行底層的實(shí)現(xiàn),而提供Python的接口,是比較流行的做法。女兒前段時(shí)間很喜歡看《海底小縱隊(duì)》,我也跟著看了幾集。里面有一個(gè)叫巴克的北極熊和一個(gè)叫呱唧的貓。他倆經(jīng)常一起出去執(zhí)行任務(wù),因?yàn)榻M合了北極熊的力量和貓的敏捷,他倆總是能出色地完成各種考驗(yàn)?,F(xiàn)在想想,如果把C++比喻成北極熊,而把Python比喻成貓,也是十分合適的。
說回Qt/PyQt的編譯?,F(xiàn)在常用的Qt版本有Qt4和Qt5兩種。目前來說還是支持Qt4的開源庫多一些。而Qt4相較于Qt5,我暫時(shí)還沒有感受到明顯的弱項(xiàng)。所以我電腦上的環(huán)境目前是Qt4的最高版本-4.8.11。如果是安裝Qt,在Ubuntu上可以直接用sudo apt install來安裝Qt的開發(fā)庫。在Windows上有相應(yīng)的安裝程序來安裝。那PyQt呢,得看你用什么python版本。有的python版本,用pip就可以直接安裝,而又的python版本,就是無法直接安裝。而好死不死,由于某種原因,我必須使用的python版本,用pip就是無法安裝PyQt4。這個(gè)時(shí)候就要通過源碼來編譯。
上riverbankcomputing的網(wǎng)站,上面有下PyQt4,PyQt5以及SIP的源碼。SIP,是編譯PyQt所必須使用的編譯工具。所以編譯PyQt的順序是這樣:
- 安裝好Qt。
- 保證qmake在Windows的控制臺或Ubuntu的終端上是可用的。
- 下載SIP源碼包,安裝SIP。
- 下載PyQt源碼包,安裝。
這里比較好玩的地方在于,看看Qt到PyQt到底是怎么做的。PyQt的源碼包中沒有Qt的任何原文件,只有一些sip定義的文件,還有其它的一些工具軟件。也就是說,PyQt的具體實(shí)現(xiàn),真的就是在Qt中。另外,在整個(gè)編譯過程中,并不需要對Qt本身進(jìn)行修改。那SIP的做法很好啊~后來,我看了一下SIP的文檔。在Introduction中,是這么說的:
SIP是一個(gè)工具,能對C/C++庫自動生成Python-bindings。SIP最初是在1998年被開發(fā)出來用于PyQt——the Python bindings for the Qt GUI toolkit,但是它也同樣適用于C/C++庫。
本版SIP生成的綁定適用于Python2.3及以后版本,包括Python3。
還有許多跟SIP功能類似的工具。其中一個(gè)就是SWIG,事實(shí)上SIP之所以被叫做SIP是起初就是一個(gè)小的SWIG。與SWIG不同的是,SIP是專門設(shè)計(jì)用于將Python和C/C++集成在一起,并不遺余力地使集成更加緊密。
其特點(diǎn)如下(不全,摘錄):
- 綁定能夠被快速加載,并且最大限度地減少了內(nèi)存消耗,特別是在僅使用大型庫的小型子集時(shí)
- 標(biāo)準(zhǔn)Python和C/C++數(shù)據(jù)類型之間的自動轉(zhuǎn)換
- 用不同的參數(shù)簽名重載函數(shù)和方法
- 支持Python的關(guān)鍵字參數(shù)語法
- 支持明確指定的和自動生成的文檔注釋
- 能夠訪問C++類的protected方法
- 能夠定義一個(gè)Python類,它是C++類的一個(gè)子類,包括抽象的C++類
- Python子類可以實(shí)現(xiàn)__dtor __()方法,該方法將從C++類的虛擬析構(gòu)函數(shù)中調(diào)用
- 支持普通的C++函數(shù),類方法,靜態(tài)類方法,虛擬類方法和抽象類方法
- 能夠在Python中重新實(shí)現(xiàn)C++的虛擬方法和抽象方法
- 支持全局變量和類變量
- 支持全局操作符和類操作符
- 支持C++命名空間
- 支持C++模版
- 支持C++異常并以Python異常的方式捕獲它們
- 支持棄用警告
- 能夠定義C++類與相似的Python數(shù)據(jù)類型之間的映射,并且是被自動調(diào)用的
- 能夠自動利用任何可用的運(yùn)行時(shí)類型信息來確保Python實(shí)例對象的類匹配相應(yīng)C ++實(shí)例的類
- 能夠改變Python對象的類型及元類型,用來包裝C/C++的數(shù)據(jù)類型
- 全面支持Python全局解釋器鎖定,能夠讓指定的C++函數(shù)阻塞,允許釋放鎖定從而運(yùn)行其他Python線程
- 支持C++實(shí)例所有權(quán)的概念(例如,代碼的哪一部分負(fù)責(zé)調(diào)用實(shí)例的析構(gòu)函數(shù))以及在應(yīng)用執(zhí)行期間所有權(quán)可能如何改變
- 能夠生成一個(gè)C++類庫的綁定,這個(gè)C++類庫是在另外一個(gè)已經(jīng)生成了綁定的C++類庫的基礎(chǔ)上建立的,因此不同的綁定能夠集成和并正確地共享代碼
- 有一個(gè)復(fù)雜的版本控制系統(tǒng),從而允許在一組簡單的規(guī)范文件中描述C++類庫的完整生命周期,包括任何平臺特有的或者可選的特征。
- SIP 可以在 UNIX, Linux, Windows, MacOS/X, Android and iOS下使用。
另外,看了一下Using SIP的文檔。其中比較復(fù)雜的那個(gè)例子,說明了如何使用Qt來編寫一個(gè)控件,然后把它放到PyQt的工程中。這么做是非常有意義的。因?yàn)椋?/p>
- 如果控件本身的邏輯比較復(fù)雜,用Python實(shí)現(xiàn)比較慢,那就可以用C++來實(shí)現(xiàn),只在PyQt中調(diào)用即可。
- 萬一看到別人用C++的Qt實(shí)現(xiàn)了一個(gè)自己想用的控件,可以在幾乎不改人家的源代碼的情況下,拿過來嵌入到自己的PyQt項(xiàng)目中。(不過有一個(gè)前提,人家用Qt4,你就得用PyQt4,人家用Qt5,你就得用PyQt5)
注:官網(wǎng)提供了Qt4到PyQt4的例程,github上有一個(gè)Qt5到PyQt5的例程。在Google搜索Qt5ToPyQt5即可。