天天看點

使用PyQt來編寫第一個Python GUI程式

簡介

許多人在學習如何建立一個 GUI 應用的時候都感到十分的困難。其中最重要的原因是,他們不知道應該從何下手。大多數的教程都隻有文字,但事實上僅僅依靠文字很難學會 GUI 程式設計,因為 GUI 應用大多數都是基于視覺上的。

我們将通過建立一個簡單的 GUI 應用來避免上面提到的這些問題,并且向你展示着手開始這件事其實是多麼的簡單。一旦你明白了這些基本的知識,以後的進一步學習将會變得十分的容易。

這就是我們即将完成的東西:

使用PyQt來編寫第一個Python GUI程式

這是一個簡單的 GUI 應用,根據輸入的價格(price)和稅率(tax rate),計算出最終的價格(final price)。

大多數的教程都試圖直接通過代碼來對 GUI 應用進行布局,但是這樣做實在是很費勁。我們将要做的是利用優秀的 QT Designer 工具來對我們的應用進行布局。

使用PyQt來編寫第一個Python GUI程式

是以不要再勞神費力的用代碼來設計界面了。現在開始所有的東西都将通過圖形界面來搞定。

前提條件

開始着手

提示:當你需要檢視更多細節的時候,你可以通過點選下方的任意圖檔來檢視其原圖。(譯者注:你可能需要檢視原始連結來檢視原圖)

打開 QT Designer。在彈出的視窗中,選擇 Main Window,這樣它會給你一個空白的畫闆。

使用PyQt來編寫第一個Python GUI程式

接下來在左側選擇<code>Text Edit</code>:

使用PyQt來編寫第一個Python GUI程式

将<code>Text Edit</code> 拖動到主視窗:

使用PyQt來編寫第一個Python GUI程式

看見右邊我粗略的用紅圈框起來的部分了嗎?那就是定義這個對象的名字的地方。這個名字将是我們通過 Python 代碼調用到這個對象的變量名,是以請盡量取一個有意義的名稱。

使用PyQt來編寫第一個Python GUI程式

我将它取名為<code>price_box</code>,因為我們會在這裡輸入價格。然後我們需要給這個輸入框添加一個 label,以便讓使用者更加清楚這個輸入框的作用。

使用PyQt來編寫第一個Python GUI程式

我在上圖中圈出了 label。把它拖動到主視窗當中來。

使用PyQt來編寫第一個Python GUI程式

現在它被預設稱作<code>TextLabel</code>。輕按兩下并将其命名為<code>Price</code>。你還可以将這段文字字型加大并且設定為粗體,就像下邊看到的這樣:

使用PyQt來編寫第一個Python GUI程式

對于稅率(tax)輸入框,我們會使用另外的一個東西。找到<code>spin box</code>:

使用PyQt來編寫第一個Python GUI程式

左側用圈框起來的部分就是一個<code>spin box</code>。它會限定你能輸入的值。其實并不是非得要用<code>spin box</code>,這樣做隻不過是為了更好地展示 QT Creator 所能提供的各種不同的元件。将<code>spin box</code> 拖到視窗中。然後我們要做的第一件事情就是将<code>objectName</code> 改為一個有意義的名字,例如我将其設定為<code>tax_rate</code>。請記住這将會是你在 Python 代碼中調用它的時候會使用到的變量名。

使用PyQt來編寫第一個Python GUI程式

我們可以為我們的<code>spin box</code> 設定一個預設值。我選擇将其設定為 20:

使用PyQt來編寫第一個Python GUI程式

如果你仔細觀察上圖,你會發現我們也可以設定它的最小值和最大值。不過我并不打算去更改他們。

同樣地,我會為它添加一個标簽叫做<code>Tax Rate</code>。然後看看我們接下來會用到的圈起來的<code>Push Button</code>:

使用PyQt來編寫第一個Python GUI程式

好的,現在選擇<code>Push Button</code> 然後将其拖動到我們的視窗中來。

使用PyQt來編寫第一個Python GUI程式

這個按鈕現在顯示的是<code>PushButton</code>,這并不是一個很有意義的名字。到了這一步,你應該知道該怎麼更改它了。不過在此之前,我們要把這個按鈕的名字(不是顯示用的文字列)改為<code>calc_tax_button</code>。

使用PyQt來編寫第一個Python GUI程式

然後,我們可以修改真正的顯示文字列了:

使用PyQt來編寫第一個Python GUI程式

然後選擇另外一個<code>Text Edit</code> 并将其拖動到視窗中。你不需要給它添加标簽,因為我們會把我們的結果輸出到這裡。把它的名字改為<code>results_window</code>(下圖中沒有畫出來,但你應該已經知道該如何操作了)。

使用PyQt來編寫第一個Python GUI程式

如果你覺得需要的話,你可以添加一個大标題。這是一個簡單的<code>label box</code> 并且将字型加大了。

使用PyQt來編寫第一個Python GUI程式

現在儲存你的成果:

使用PyQt來編寫第一個Python GUI程式

這個檔案在下一部分我們編寫代碼的時候将會用到,是以最好把它存在一個我們友善通路的地方。

我們建立的隻是一個簡單的 XML 檔案。用任意一個文本編輯器打開它,你可以看到這樣的内容:

使用PyQt來編寫第一個Python GUI程式

編寫代碼

Qt 代碼是面向對象的,并且簡單易學。所有我們添加的元件都是一個對象,并且都擁有自己的方法比如<code>toPlainText()</code>(用來讀取輸入框中的值)。這讓它使用起來非常友善。

這些代碼非常有用,每當你想要建立一個新的 PyQt 項目的時候,就在這段代碼的基礎上添加你自己的代碼吧。

這段代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<code>import</code> <code>sys</code>

<code>from</code> <code>PyQt4</code><code>import</code> <code>QtCore, QtGui, uic</code>

<code>qtCreatorFile</code><code>=</code> <code>""</code><code># Enter file here.</code>

<code>Ui_MainWindow, QtBaseClass</code><code>=</code> <code>uic.loadUiType(qtCreatorFile)</code>

<code>class</code> <code>MyApp(QtGui.QMainWindow, Ui_MainWindow):</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>):</code>

<code>        </code><code>QtGui.QMainWindow.__init__(</code><code>self</code><code>)</code>

<code>        </code><code>Ui_MainWindow.__init__(</code><code>self</code><code>)</code>

<code>        </code><code>self</code><code>.setupUi(</code><code>self</code><code>)</code>

<code>if</code> <code>__name__</code><code>=</code><code>=</code> <code>"__main__"</code><code>:</code>

<code>    </code><code>app</code><code>=</code> <code>QtGui.QApplication(sys.argv)</code>

<code>    </code><code>window</code><code>=</code> <code>MyApp()</code>

<code>    </code><code>window.show()</code>

<code>    </code><code>sys.exit(app.exec_())</code>

其中需要注意的是第三行:

你需要在這裡填入你先前建立的檔案的位址。這個檔案将會被内置的函數載入:

讓我們大緻地看一看這段代碼:

這段主程式建立了一個新的 Qt Gui 應用。,每個 QT 應用都可以通過指令行進行配置,是以必須傳入<code>sys.argv</code> 參數。不過現在我們用不到這個。最後,我們建立了一個<code>MyApp</code> 類,這個類繼承于 Qt 庫并且調用了父類的初始化函數:

你不一定非得要了解這些代碼的細節。你隻需要在它的基礎上繼續開發就好了。

下載下傳<code>pyqt_skeleton.py</code> 這個檔案,并将它重命名為<code>pyqt_first.py</code>。這是因為我們不想去改動到源檔案。然後要做的第一件事就是在代碼中導入我們自己的 XML 檔案,這個 XML 檔案包含了我們的這個 GUI 資訊。将下面的這一行:

替換為

<code>qtCreatorFile</code><code>=</code>  <code>"tax_calc.ui"</code>

這樣就能把我們的 GUI 檔案載入到記憶體中。現在,我們的 GUI 中最關鍵的元件就是我們的這個按鈕了。一旦我們按下這個按鈕,就會發生一些神奇的事情。到底會發生什麼?這就需要我們告訴代碼當按下<code>Calculate Tax</code> 按鈕的時候該怎麼做了。在<code>__init__</code> 函數中,添加如下的内容:

<code>self</code><code>.calc_tax_button.clicked.connect(</code><code>self</code><code>.CalculateTax)</code>

這段代碼有什麼用?還記得我們把按鈕命名為了<code>calc_tax_button</code> 嗎?(這是這個按鈕對象的名字,不是按鈕上顯示的提示字元串。)<code>clicked</code> 是一個内置的函數,當有按鈕被點選的時候它會被自動調用(很神奇吧)。所有的 QT 元件都有特定的函數,你可以通過 Google 來檢視詳細。這段代碼的最後部分是<code>connect(self.CalculateTax)</code>。這意味着這個按鈕會被連結到一個叫做<code>self.CalculateTax</code> 的函數,這樣以後每當使用者按下這個按鈕的時候,這段代碼都會被調用。

我們還沒有實作這個函數。是以讓我們動手開始寫吧。

在<code>MyApp</code> 類中,添加另外一個函數。我們需要先看看整個函數,然後再去了解它的細節:

<code>def</code> <code>CalculateTax(</code><code>self</code><code>):</code>

<code>        </code><code>price</code><code>=</code> <code>int</code><code>(</code><code>self</code><code>.price_box.toPlainText())</code>

<code>        </code><code>tax</code><code>=</code> <code>(</code><code>self</code><code>.tax_rate.value())</code>

<code>        </code><code>total_price</code><code>=</code> <code>price </code><code>+</code> <code>((tax</code><code>/</code> <code>100</code><code>)</code><code>*</code> <code>price)</code>

<code>        </code><code>total_price_string</code><code>=</code> <code>"The total price with tax is: "</code> <code>+</code> <code>str</code><code>(total_price)</code>

<code>        </code><code>self</code><code>.results_window.setText(total_price_string)</code>

好了,讓我們一行一行的分析上面的代碼。

我們現在要做兩件事:讀取價格和稅率,然後計算最終的價格。好了開始吧。請記住,我們要通過我們設定的名字來調用這些元件(這就是我讓你不要用預設的通用名稱比如<code>box1</code> 的原因,否則的話我們在寫代碼的時候會很惱火)。

<code>price</code><code>=</code> <code>int</code><code>(</code><code>self</code><code>.price_box.toPlainText())</code>

<code>price_box.toPlainText()</code> 是一個内置的可以讀取輸入框中的值的函數。順便提一句,雖然你用得多了以後肯定能記住這些函數,因為他們的名字取得很規範,但是你沒必要一開始就去記憶所有這些函數。我每次都是通過 Google 諸如 “Qt Textbox 讀取資料”一類的關鍵字來找到我所需要的函數。

通過函數讀取到的是一個 string 類型的值,是以我們需要把他轉換成 integer 類型并存在一個<code>price</code>變量中。

然後讀取稅率:

<code>tax</code><code>=</code> <code>(</code><code>self</code><code>.tax_rate.value())</code>

同樣的,<code>value()</code> 是讀取<code>spinbox</code> 中值的函數。感謝 Google。

我們現在已經得到了以上兩個值,這樣我們就能用非常高大上的數學公式來計算我們的最終價格了:

<code>total_price</code><code>=</code> <code>price </code><code>+</code> <code>((tax</code><code>/</code> <code>100</code><code>)</code><code>*</code> <code>price)</code>

<code>total_price_string</code><code>=</code> <code>"The total price with tax is: "</code> <code>+</code> <code>str</code><code>(total_price)</code>

我們建立了一個 string 變量來儲存我們的最終價格。因為最終直接顯示在應用上的将會是一個 string 類型的值:

<code>self</code><code>.results_window.setText(total_price_string)</code>

在<code>results_window</code> 中,我們調用了<code>setText()</code> 函數,它能顯示我們計算出的最終價格的字元串。

最後運作我們寫好的程式:

<code>python pyqt_first.py</code>

使用PyQt來編寫第一個Python GUI程式
使用PyQt來編寫第一個Python GUI程式

好了,這就是一個簡單的 PyQt 教程。

如果你還想要體驗更多好玩兒的東西,你可以試着用一用别的元件,不過先提醒一句,你要是放了太多的元件在你的應用中的話,用起來可能會有點費勁…