2009年4月23日

[PyQt 教學] Part 3: 起步走

[PyQt 教學] Part 2: 建構開發環境

第一個 GUI 程式:

#!/usr/bin/env python

import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

widget = QWidget()
widget.show()

app.exec_()

摳起來存成 first.py 後,雙點 or 進 terminal 輸入 python first.py 就可以執行了!( Windows® 下可能得用完整路徑 C:\Python26\python.exe )

一行一行來看 code:

#!/usr/bin/env python:Windows® 下沒作用。在 Unix 下執行時可幫助尋找 Python 直譯器。

import sys:Qt 程式初始化時需要用到一些參數 ( sys.argv )。

from PyQt4.QtGui import *:導入 PyQt4 裡面的圖形介面庫,包含許多圖形元件 ( widget / window gadget )。之後用到的 QWidget 就是屬於這個庫的。

這裡用了完整導入的語法 ( 而非 from PyQt4 import QtGui ),以免之後得打 QtGui.QApplicationQtGui.QWidget 之類又臭又長的 scope name。

( 基本上,Qt 對自身組件的命名都有前綴 Q,想撞到也難...... 所以應該不用太怕 namespace pollution。)

app = QApplication(sys.argv):每個 Qt GUI 程式都需要一個 ( 唯一一個 ) QApplication,負責管理 Qt 資源、控制執行流程和有的沒的例行事務。雖然很少會用 command line 來開 GUI 程式,還是得帶 sys.argv 參數來初始化它......

接下來兩行,搞出 QWidget instance 並調用 member function show() 讓它顯示出來。所有圖形元件被創造時都是 hidden 狀態,可以先設定好它的外觀再顯示出來,免得一直重繪造成畫面閃爍。

app.exec_():讓 QApplication 進入 event loop,直到程式接收結束訊號。原本 C++ Qt 是用 memfunc exec(),但在 Python 中名稱已被佔用,所以不幸得改成這鳥名......

不懂某些語法的必要性的話也沒關係,總之這些是基本的 code pattern,依樣畫葫蘆就是,以後長大就會慢慢懂了......。我當初看《C++ GUI Programming with Qt 4》時也是滿腦子 "WTF" = =

總結:導入相關庫 → 初始化 QApplication → 把想要的 widgets 搞定 → 開始執行 QApplication event loop。


很明顯,這是個一點 p 用也沒的拉雞程式。除了拉來拉去改變大小以外啥 p 也做不了。但是其中卻蘊含了不少東西......


Qt GUI 採用 Event-driven architecture:有事件發生時就處理之;沒事件發生 or 這事件不干我屁事時,就卡在那邊乾等新的事件。

Event」指啥?包括了滑鼠點擊、游標飄過、鍵盤輸入等;event 發生後,會被轉交到 event handler 以決定該怎麼應對處理。

以我們的第一個程式來說,因為並沒指定該怎麼特別處理上述那些事件,所以就讓它們隨風而逝不了了之了。但是像視窗大小改變、最大化等事件,event handler 就知道該調用重繪函式改變外觀 ( class 自己會搞定,程式設計師去泡咖啡準備加班便可 )。

Event-driven 是很重要的概念 ( 據說現行圖形系統都是用這種方式運作的...... );請謹記,就算是游標掃過去,也會產生 event 的。「繼承並改寫 event handler」,可讓程式依自己想要的方式處理事件。


接下來看第二個程式:

#!/usr/bin/env python

import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

widget = QWidget()
widget.resize(200, 150)
widget.move(500, 400)
widget.setWindowTitle("Hello World")
widget.show()

app.exec_()


只多了 3 行,調用 QWidget instance 的一些 memfunc 改變視窗狀態。包括了改變視窗大小、把視窗移動到螢幕特定位置 ( 而不像初體驗一樣,任由作業系統分派 ),以及改變視窗的 title。

( 初學程式的人可能會問:怎麼知道有啥函式可以呼叫呢?

沒事就多熟悉這個 framework 和 API,看看有啥函式可以摳吧...... 別無它法了。Qt API 和命名方式都頗為清楚有規律,算是賞心悅目,可以多翻翻 =3= )

QWidget 的文檔可以看出來,雖然這玩意兒長得空空如也毫不起眼,卻有兩百多個函式可供呼叫。由繼承架構更可知道,Qt 中所有的圖形元件都繼承自 QWidget (||°3°)

因此,QWidget class 有兩大功用:一是提供海量函式讓 child class 繼承使用;二是做為空空的容器,拿來裝 child widgets。以後會慢慢提到......


下次再見 (||°3°)

[PyQt 教學] Part 4: Layout Management

7 則留言:

  1. Hi there:

    謝謝你的分享。
    我正在學PyQt,有Python基礎但不會C++。
    一直在找PyQt教學,終於讓我找到一個滿意的了。
    你所附上的code是我找到的唯一可以work的,而且又附有圖片。人家說一張圖勝過千萬字,就是這個道理吧。

    謝謝你拉,打擾了。^^

    回覆刪除
  2. 呵呵,謝謝
    希望對你有幫助

    回覆刪除
  3. 請問要學PyQt, 是否一定要先學會Python跟Qt(C++開發)兩者呢?

    回覆刪除
  4. 我這系列文章是假定讀者原本沒摸過 Qt 的。而且內容也只摸到 Qt 的邊而已...

    至於 Python,當然能會是最好。不過如果已經有其它高階語言經驗的話,就算現學現賣 Python 也是不會太費心的 =3=

    回覆刪除
  5. 如果要學得更深入的話,當然是要兩項都通囉...
    不過可以用這系列文章當入門磚就是了

    PyQt 沒有較新的書可以參考,就用內附的 example 和 Qt 書籍來學習吧

    回覆刪除
  6. 謝謝您的說明 對於自學初學者有很大的幫助

    回覆刪除