PyQt4 25行的彈出式鬧鐘
應用特點
- 控制臺啟動
- 沒有裝飾欄
- 沒有標題欄
- 沒有系統菜單
- 沒有關閉按鈕
運行效果
啟動後,程序會在後臺默默運行,僅是簡單地記錄時間直到達到給定的時間。此時,程序會彈出一個文本消息窗口。大約窗口顯示後一分鐘,程序會自動終止。
源代碼
# encoding:utf-8
import sys
import time
from PyQt4 import QtCore
from PyQt4 import QtGui
# sys.argv用於訪問命令行參數
app = QtGui.QApplication(sys.argv)
# handle the argv
try:
due = QtCore.QTime.currentTime()
message = 'Alert!'
if len(sys.argv) < 2:
raise ValueError
hours, mins = sys.argv[1].split(':')
due = QtCore.QTime(int(hours), int(mins))
if not due.isValid():
raise ValueError
if len(sys.argv) > 2:
message = ' '.join(sys.argv[2:])
except ValueError:
# 24hr clock
message = 'Usage: alarm_clock.py HH:MM [optional message]'
while QtCore.QTime.currentTime() < due:
# 20 seconds
time.sleep(20)
label = QtGui.QLabel('<font color=red size=72><b>' + message + '</b></font>')
label.setWindowFlags(QtCore.Qt.SplashScreen)
label.show()
# 1 minute
QtCore.QTimer.singleShot(60000, app.quit)
app.exec_()
解析
import sys
import time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
導入sys
模塊,是因為我們想訪問包含在sys.argv
列表中的那些命令行參數,導入·模塊,則是因為我們需要它的sleep()
函數;而導人這兩個PyQt
模塊,則是因為需要使用 GUI
和 QTime
類。
# sys.argv用於訪問命令行參數
app = QtGui.QApplication(sys.argv)
先從創建QApplication
對象開始。每個PyQt GUI
應用程序都必須有一個QApplication
對象。這個對象會提供訪問全局信息的能力,如應用程序的目錄、屏幕大小(以及對於多線程 系統來說,這個應用程序是在哪個屏上)等。這個對象還會提供稍後要討論的事件循環。
在創建QApplication
對象時,給它傳遞了命令行參數;這是因為,PyQt
可以識別一些 自己的參數,如-geometry
和-style
,所以需要給一個讓它讀到這些參數的機會。如果 QApplication
能夠識別任意一個參數,它就會對它們進行一些操作,並將其從給定的參數 列表中移除掉。QApplication
能夠識別的那些參數列示在QApplication
的初始化文檔中。
當程序中存在上述語句時,會報錯如下:
QWidget: Must construct a QApplication before a QPaintDevice
參數處理:
# handle the argv
try:
due = QtCore.QTime.currentTime()
message = 'Alert!'
if len(sys.argv) < 2:
raise ValueError
hours, mins = sys.argv[1].split(':')
due = QtCore.QTime(int(hours), int(mins))
if not due.isValid():
raise ValueError
if len(sys.argv) > 2:
message = ' '.join(sys.argv[2:])
except ValueError:
# 24hr clock
message = 'Usage: alarm_clock.py HH:MM [optional message]'
在比較靠後的地方,這個程序需要一個時間點,所以把due
變量值設定為現在的時間。我們 還提供了一個默認消息。如果用戶沒有給定哪怕至少一個的命令行參數值(時間),就會拋出 (raise
)一個ValueError
異常。這樣就會顯示一個當前時間,並且會給出含有“用法”錯誤的消息
如果第一個參數不含冒號,那麽在嘗試調用split
將兩個元素解包時,就將觸發一個ValueError
的異常。如果小時數和分鐘數不是有效的數字,那麽int()
將會觸發一個ValueError
異常; 而如果小時數和分鐘數超限,導致成了無效的QTime
, 那麽就需要自 己來觸 發一個ValueError
異常。盡管Python提供了自己的date
和time
類,但PyQt
的date
和time
類通常會顯得更為方便些,所以推薦使用PyQt
的這些類。
如果該time
有效,那麽就把這條消息與其他命令行參數(如果還有的話)用空格分隔開; 如果沒有其他參數,就用開頭設置的默認信息“Alert
!”來代替之(當一個程序是用命令行方式 啟動時,會給定一系列的參數,第一個稱為調用名,而剩下的其他非空字符,也就是輸人命令 行中的其他每個單詞,都稱為字符序列。這些字符序列或許會被shell
改變,例如,可能會用 通配符進行匹配。Python
自己的字符序列位於sys.argv
列表中)。
while QtCore.QTime.currentTime() < due:
# 20 seconds
time.sleep(20)
把當前時間和目標時間連續不斷地進行循環比較。如果當前時間超過了目標時間,循環就會停止。原本是可以在循環體內放一個pass
聲明(statement
)的,但如果是這樣的話,Python
就 會非常快地一遍遍執行這個循環,而過多地占用處理器可不是什麽好現象,time.sleep()
命令會讓Python
暫停處理一段時間後再繼續處理,這裏暫停的時間是20
秒。這樣就可以讓機器上的其他程序也能夠得到更多的運行機會,因為我們也不想在等這個程序到達截止時間的期間什麽也不做。暫且先不提創建QApplication
對象,目前所做的僅僅就是標準的控制臺程序設計工作。
label = QtGui.QLabel('<font color=red size=72><b>' + message + '</b></font>')
label.setWindowFlags(QtCore.Qt.SplashScreen)
label.show()
# 1 minute
QtCore.QTimer.singleShot(60000, app.quit)
app.exec_()
在創建了 QApplication
對象後,就會顯示一條消息,因為截止時間已到,所以現在就可以 創建程序了。一個GUI程序需要一些窗口部件,這樣就需要用有一個標簽(labe
)來顯示該消 息。QLabel
可以接收HTML
文本,所以就給它一個HTML
字符串,讓它能夠將這段消息顯示 為加黑、紅色、大小為72點素(point
)①。
在PyQt
中,任何窗口部件都可以作為頂級窗口,即使是按鈕和標簽都行。當窗口部件這麽用的時候,PyQt
就會自動給它加一個標題欄。在這個應用程序中,並不想要一個標題欄,所 以要把該標簽的各個窗口標記(flag
)均設置為閃屏(splash screen
)模式,因為這種模式不會有標題欄了。一旦把要作為窗口的標簽設置完畢,就可以對其調用show()
函數了。此時,該標 簽窗口卻沒有顯示出來show ()
的調用僅僅是計劃執行一個“重繪事件”(paim event
),也就 是說,show ()
會向QApplication
對象的事件隊列中添加一個新的事件,以請求對特定的窗口部件進行繪制。
接下來,會設置一個單次定時器(single-shot timer
)。這是因為Python
庫的time.sleep
函數使用的時間是秒,而QTiraer.singleShot()
函數使用的是毫秒。給singleShot()
方法 兩個參數:讓這個時間需要持續多長(這裏是1分鐘),時間到期後調用哪個函數或者方法。
用PyQt
的術語來說,上述給出的方法或者函數叫做“槽"(slot),盡管在PyQt
的文檔中,也會用術語“可調用”(callable
)、“ Python 槽
”(Python slot
)和“Qt
”槽(Qt slot
)來區分 Python
的 _slots_
,這是在Python
語言指南(Python Language Reference
)中給出的一個新特性類。所以現在要計劃執行兩個事件:一個是需要立即執行的繪制(paint
)事件,一個是需要在一分鐘後執行的定時器(timer
)超時事件。
調用app.exec_()
會開始執行QApplication
對象的事件循環①。第一個事件就是繪制事件,所以標簽窗口會帶著給定的消息顯示在屏幕上。大約一分鐘之後,會發生定時器的超時 事件,此時會調用QApplication.quit
方法。這個方法會幹凈地結束掉該GUI
應用程序。 它會關閉所有已打開的窗口,釋放所有占用的資源,然後退出程序。
PyQt4 25行的彈出式鬧鐘