PyQt

**PyQt** 是 Python 語言的 GUI 編程解決方案之一。可以用來代替 Python 內建的 Tkinter。其它替代者還有 PyGTK、wxPython 等。與 Qt 一樣，PyQt 是一個自由軟體。PyQt 是 PyKDE 的基礎。

PyQt 的開發者是英國的「Riverbank Computing」公司。與 4.5 版本之前的 Qt 一樣，它提供了 GPL 與商業協定兩種授權方式，因此它可以免費地用於自由軟體的開發。不過目前尚不提供 LGPL 授權方式。PyQt 可以執行於 Microsoft Windows、Mac OS X、Linux 以及 Unix 的多數變種上。

2009 年 8 月，Qt 的開發公司諾基亞發布 PySide，提供與 PyQt 類似的功能，但提供了 LGPL 授權。主要原因是「Riverbank Computing」不願以 LGPL 授權發布 PyQt。

自 4.5 版本以後，PyQt 同時支援 Python 2.x 與 Python 3.x。但是在 API 方面有所區別，最主要的是執行在 Python 3.x 下的 PyQt 不使用 `QString`，而是 `str`。另外，之前為了避開 Python 2.x 關鍵詞限制的 `exec_()`、`print_()` 兩個函式現在重新命名為 `exec()`，`print()`。

## PyQt 組件

PyQt 包含了大約 440 個類型、超過 6000 個的函式和方法。

* 「QtCore」模組主要包含了一些非 GUI 的基礎功能，包含事件迴圈與 Qt 的訊號機制。此外，還提供了跨平台的 Unicode、執行緒、記憶體對映檔案、共享記憶體、正規表示式和使用者設定。
* 「QtGui」模組包含了大多數的 GUI 類型。包含按鈕、文字方塊、列表等常見控制項，還包含了基於 MVC 設計模式的列表、表格、樹型控制項。同時還提供了一個能夠容納成千上萬個元素的畫布控制項，其中可以放置各種控制項和圖形。此外，QtGui 還支援介面動畫與介面狀態機編程。
* 「QtNetwork」模組可以用於編寫非阻塞式的 UDP、TCP 程式。還包含了 DNS、HTTP 與 FTP 的客戶端。
* 「QtOpenGL」模組允許 Qt 程式使用 OpenGL 彩現 3D 圖形，而且不必大量更改代碼。
* 「QtSql」模組支援多種 SQL 資料庫。包括 SQLite、ODBC、MySQL、PostgreSQL、Oracle。還提供了一個基於 MVC 模式的資料模型，與 QtGui 的的表格控制項配合使用。
* 「QtXml」包含一個 XML 直譯器，同時支援 SAX 和 DOM 兩種編程方式。
* 「QtWebkit」與「QtScript」兩個子模組支援 WebKit 與 ECMAScript 手稿語言
* 「Phonon」子模組支援進階的多媒體編程。包含音訊播放器、影片播放器與聲效處理。
* 「uic」子模組能夠將 Qt 的表單檔案轉換為 Python 代碼，能夠即時讀入表單檔案並且顯示出來。它依賴於 QtXml 模組。「QScintilla」子模組包含一個基於 Scintilla 的文字編輯器控制項，Eric IDE 使用它作為代碼編輯器。「QtMultimedia」提供了底層的多媒體支援，現在多數開發者改用 Phonon 模組。「QtSvg」支援 SVG 1.2 Tiny 的靜態標準，用於顯示與儲存 SVG 格式的圖形。

## 簡單例子

下面一段代碼演示了一個簡單的 PyQt 程式，它的功能是在表單內顯示一個按鈕，當按下按鈕時，要求使用者輸入名字。根據使用者是否輸入了名字，會分別顯示兩種問候語。

## signal 和 slot

Qt 採用了 signal 和 slot 的概念來處理 GUI 程式中的使用者事件。PyQt 同樣支援這種方法，還進而針對 Python 的特點增強了某些功能。任何 Python 類型都可以定義 signal 和 slot，並與 GUI 控制項的 signal 和 slot 相連接。PyQt 支援 old-style 與 new-style 兩種連接方式。不過，目前一般推薦使用 new-style connection。因為它還支援連接到 Python 函式，而且看起來也比較 pythonic。

`QMetaObject.connectSlotsByName(obj)` 函式可以幫助程式設計師自動連接 signal 和 slot。使用它可以免去很多代碼。

## Qt 設計器

Qt 設計器是 Qt 所包含的視覺化 UI 設計器。在安裝 PyQt 時，可以選擇安裝 Qt 設計器。它使用拖拉操作來設計圖形介面。在設計的同時，還能夠直接預覽最終的表單效體。當表單很複雜或者整個程式需要大量的表單時，Qt 設計器可以節省大量的代碼。不過稍有改變的是，設計好表單後需要執行 pyuic4 這個指令碼，將表單檔案轉換成 Python 代碼。仍以「簡單例子」中的小程式為例，首先使用 Qt 設計器設計出表單。假定儲存為 "h:\pyqt\_example.ui"。表單檔案內容是：

使用如下命令將表單檔案轉換成 Python 代碼（適用於 Windows 系統）：

新的範例程式是（假定儲存為 h:\pyqt\_example.py）：

## PyQt 的優劣

### 優勢

* PyQt 的 API 與 Qt 類似，Qt 的文件通常仍然可以應用於 PyQt。因此，PyQt 的文件比 PyGTK、wxPython、Tkinter 等 GUI 編程庫的文件豐富得多。
* 如果程式設計師具備使用 Qt 的經驗，一般很快就可以過渡到 PyQt 上。而使用 PyQt 的程式設計師，如果同時精通 C++ 的話，也可以很快地過渡到 Qt 平台上。
* 利用 SIP，大多數為 Qt 開發的控制項可以方便地 port 到 PyQt。—— 然而，SIP 也需要一些學習成本。
* 有方便的周邊工具支援 PyQt。如 QtDesigner，可以使用拖拉式的方法來設計介面，簡單易用。Eric6，一個使用 PyQt 設計的 Python IDE，對 PyQt 有特殊的支援。

### 劣勢

* 由於 PyQt 同時使用 Qt 以及 Python 的兩種記憶體管理方法，所以在使用 PyQt 的過程中要注意避免記憶體泄露以及懸掛指標。
* 執行時龐大，在 Windows 平台，只使用 PyQt.QtCore 與 PyQt.QtGui 兩個子模組時，壓縮後至少需要 4.09M
* 需要學習一些 C++ 知識，主要是 C++ 類型、記憶體管理兩個方面，以便於閱讀 Qt 文件和理解 PyQt 的行為。

## SIP

SIP 是一個自動為 C 和 C++ 庫生成 Python 擴充模組的工具。為了方便開發 PyQt，SIP 於 1998 被「Riverbank Computing」公司創造出來。不過，SIP 不專用於 PyQt，而是適用於所有的 C 和 C++ 庫。

使用 SIP 時，程式設計師首先要編寫一個特殊的 ".sip" 檔案，使用類似於 C++ 的語法在其中描述擴充模組所提供的類型與函式。然後用 SIP 將這個檔案轉化為 C++ 代碼。最終編譯，與 C、C++ 庫連結後就成為 Python 擴充模組。".sip" 檔案類似於 C、C++ 的標頭檔。根據需要，需要程式設計師用 SIP 定義的語法添加一些 C++ 代碼中沒有的資訊。因為 SIP 不支援完整的 C++ 語法，所以不能直接使用 C++ 的標頭檔作為 ".sip" 檔案。

## 使用 PyQt 的著名應用程式

* Eric Python IDE
* Anki, a spaced repetition flashcard program
* QtiPlot, a computer program to analyze and visualize scientific data
* qt-recordMyDesktop：recordMyDesktop 的 Qt4 介面
* Kodos, Python Regular Expression Debugger

## 參考文獻

## 延伸閱讀

* Summerfield, Mark, Rapid GUI Programming with Python and Qt（Covers PyQt4） 1st, Prentice Hall: 648, October 28, 2007 [2009-04-03], ISBN978-0132354189, （原始內容存檔於 2009-03-31）
* Rempt, Boudewijn, GUI Programming with Python: QT Edition（Covers PyQt3）, OpenDocs, 2002 [2010-06-11], （原始內容存檔於 2010-04-09）

## 外部連結

* 官方網站（頁面存檔備份，存於網際網路檔案館）
* PyQT tutorial（頁面存檔備份，存於網際網路檔案館）
* PyQt 教學（頁面存檔備份，存於網際網路檔案館）