第一個 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.QApplication 和 QtGui.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°)
Hi there:
回覆刪除謝謝你的分享。
我正在學PyQt,有Python基礎但不會C++。
一直在找PyQt教學,終於讓我找到一個滿意的了。
你所附上的code是我找到的唯一可以work的,而且又附有圖片。人家說一張圖勝過千萬字,就是這個道理吧。
謝謝你拉,打擾了。^^
呵呵,謝謝
回覆刪除希望對你有幫助
請問要學PyQt, 是否一定要先學會Python跟Qt(C++開發)兩者呢?
回覆刪除我這系列文章是假定讀者原本沒摸過 Qt 的。而且內容也只摸到 Qt 的邊而已...
回覆刪除至於 Python,當然能會是最好。不過如果已經有其它高階語言經驗的話,就算現學現賣 Python 也是不會太費心的 =3=
如果要學得更深入的話,當然是要兩項都通囉...
回覆刪除不過可以用這系列文章當入門磚就是了
PyQt 沒有較新的書可以參考,就用內附的 example 和 Qt 書籍來學習吧
感謝分享
回覆刪除謝謝您的說明 對於自學初學者有很大的幫助
回覆刪除