[轉帖]在Eric4下用PyQt4編寫Python的圖形界面程序

  本文是PyQt4的入門教程。網上能搜到其它教程,但我覺得講得不是很清楚,希望這篇文章對入門者更加有幫助。

  先介紹一下PyQt4Qt4圖形庫一經發布就好評不斷,它在Python下的綁定PyQt4更是讓我眼前一亮,不但漂亮,而且開發程序非常方便。

在我看來,PyQt4最大的改進之一是它不再拘泥與各種佈局控件了,也就是說,現在寫圖形界面程序,和VB一樣可以直接拖控件到窗口上並隨便改變大小和位置了,不再像以前那樣要先放上佈局控件,再在佈局控件裏放其它控件。

PyQt4的介紹就限於此,我也不準備把它與其它Python圖形庫進行比較了,因爲經驗表明這些東西的比較,特別是QtGtk的比較總是會引起不必要的爭吵。

IDE我使用Eric4Eric4本身是用PyQt4寫的,在使用Eric4時就能體會到用PyQt4能寫出多棒的圖形界面程序。Eric4的詳細介紹與安裝請見我的其它文章。

操作系統是Windows,在Linux下的操作完全一樣。

寒喧結束,進入正題。假設我們要用Python寫一個圖形界面程序,一個對話框,裏面兩個button一個label。點擊其中一個button能改變label的內容,點擊另一個button就退出。

1. 新建工程。

打開Eric4,選擇菜單Project->New新建一個工程,名字我們取爲HelloPyQt,填好各項並選擇工程所在文件夾之後點OK,一個新的不含任何文件的工程就建好了。

2. 新建對話框。

在左側的ProjectViewer中切換到Forms選項卡(左數第二個),右鍵點空白位置,選New Form,在彈出的對話框中選擇Form類型爲Dialog,然後會問你保存到哪。我設定爲保存爲DlgHello.ui文件。點OK之後就會新建這個文件並自動打開QtDesigner。 

3. 設計界面。

先修改主對話框的屬性。選中對話框,在右側的屬性編輯器中就可以查看/修改對話框的屬性。將windowTitle改爲"Hello, PyQt",將objectName改爲"DlgHello”,前者是對話框標題,後者在以後生成代碼時有用,不建議使用默認值。

我們拖動一個Label(DisplayWidgets分類中)到對話框中,將屬性text改爲"Hello, PyQt"objectName改爲lblHello

再拖動兩個PushButton(Buttons分類中)到對話框,分別將屬性text改爲"你好"和"退出"。將屬性objectName分別改爲btnHellobtnExit

界面大概是這個樣子:


4. 處理事件。

PyQt4下,事件處理方面的術語爲“信號”和“槽”,即signalslot。事件對應信號signal,而事件的處理函數則爲slot槽。

PyQt4有一些預定義的slot,我們可以直接用,比如“退出”按鈕的slot,其實就是關閉對話框,這個slot已經在PyQt4中有定義了。對於這樣的slot,我們不用單獨寫代碼,在QtDesigner中就可以完成。而對於“你好”按鈕,我們需要自己寫代碼。對於這樣的slot,我們在QtDesigner中不做任何處理,甚至不做定義。

那麼在這個例子中,在QtDesigner裏我們只處理退出按鈕的單擊事件。

單擊“編輯信號/槽”按鈕進入信號/槽編輯模式。點中退出按鈕並拖動,會出現一個像是電路圖中的接地圖示一樣的東西,如下:

 



鬆開鼠標,就會彈出“配置連接”對話框。勾上“顯示從QWidget繼承的信號和槽”,左側選擇clicked(),右側選擇close(),點確定,就OK了。

 

如果要繼續調整對話框外觀,點擊“編輯窗口部件”按鈕回窗口編輯模式。

5. 生成界面代碼

保存之後關閉QtDesigner,會發現Eric4ProjectViewerForms選項卡中已經多出DlgHello.ui了。右擊它選擇Compile Form,就能生成Ui_DlgHello.py文件,並自動加入到工程中。在Sources選項卡中可以看到。

雙擊Ui_DlgHello.py可以看它的內容,其實是生成了一個Ui_DlgHello類。Ui_DlgHello.py是可以單獨運行的,在Eric4中直接按F2可以運行,看看初步的效果。發現單擊退出按鈕果然能直接退出程序。

不建議手動修改Ui_DlgHello.py,因爲每次改動界面並生成代碼後會將手動進行的修改給覆蓋掉。

6. 添加額外的代碼。

“你好”按鈕的單擊處理代碼還需要手寫。

PyQt4中,界面代碼與事件代碼是分開的,這一點很贊,這樣每次改界面就不會影響到事件處理的代碼了。而wxPython這一點就做得不好。

事件處理要新建一個類並繼承DlgHello類,然後在這個新類裏寫事件處理函數。新建類的工作可以交給Eric4來完成。右鍵點DlgHello.ui,選擇Generate Dialog Code,在彈出的對話框中設定ClassNameDlgHello,同時,在這個對話框中可以選擇我們感興趣的事件,Eric4會一併生成事件處理函數的定義。如下圖:

點確定之後,DlgHello.py就生成了。打開這個文件,“你好”按鈕的事件被定義爲:

    @pyqtSignature("")

    def on_btnHello_clicked(self):

        """

       Slot documentation goes here.

        """

        # TODO: not implemented yet

        raise NotImplementedError

注意這個@pyqtSignature("")自動處理了下面定義的槽slot(事件處理函數)與相對應的信號signal(事件)之間的關聯,這裏是指,單擊btnHello按鈕,就會自動執行這個函數。slot的命名規則就是”on_對像名_信號名,如果想添加新的slot,按這個規則來添加函數就行,並且在函數定義語句之前加上@pyqtSignature(""),不用再重新生成一次DlgHello.py文件。

其實另外一種關聯signalslot之間的方法是在運行裏綁定,比如按鈕對象btnAboutclicked信號的槽是about_clicked函數,那麼在__init__函數中加入這樣一句話:

        PyQt4.QtCore.QObject.connect(self.btnAbout, PyQt4.QtCore.SIGNAL("clicked()"), self.about_clicked)

那麼單擊按鈕btnAbout時就會執行about_clicked函數。

兩種方法各有長處。第一種方法簡單,第二種方法對於多個signal使用同一個slot時很有效。

on_btnHello_clicked函數改爲:

    @pyqtSignature("")

    def on_btnHello_clicked(self):

        self.lblHello.setText("你好,PyQt4")

在文件頭部加上:

import PyQt4, PyQt4.QtGui, sys

再在代碼最後加上(Ui_DlgHello.py末的幾乎一樣)

if __name__ == "__main__":

    app = PyQt4.QtGui.QApplication(sys.argv)

    dlg = DlgHello()

    dlg.show()

    sys.exit(app.exec_())

這樣就OK了。

 

7. 最後的收尾工作。

F2運行腳本,發現點擊“你好”按鈕後lblHello label中的文字是亂碼。

解決辦法很簡單,把代碼中的("你好,PyQt4")改爲(u"你好,PyQt4")就行了。PyQt4對中文的支持是很好的。代碼統一使用utf8編碼,能省去很多麻煩。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章