1. 程式人生 > >PyQt4 25行的彈出式鬧鐘

PyQt4 25行的彈出式鬧鐘

能力 -s cati 至少 qt4 訪問 pyqt statement rom

應用特點

  • 控制臺啟動
  • 沒有裝飾欄
  • 沒有標題欄
  • 沒有系統菜單
  • 沒有關閉按鈕

運行效果

技術分享圖片

啟動後,程序會在後臺默默運行,僅是簡單地記錄時間直到達到給定的時間。此時,程序會彈出一個文本消息窗口。大約窗口顯示後一分鐘,程序會自動終止。

源代碼

# 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模塊,則是因為需要使用 GUIQTime類。

# 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提供了自己的datetime類,但PyQtdatetime類通常會顯得更為方便些,所以推薦使用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行的彈出式鬧鐘