Python編程使用PyQt5制作動(dòng)態(tài)鐘表示例
前言
大家好,我是小張~
記得小時(shí)候,家里只有一個(gè)鐘表用來(lái)看時(shí)間(含有時(shí)針、分針、秒針的那種),掛在墻上噠噠噠響個(gè)不停,現(xiàn)在生活條件好了、基本人手一部手機(jī),看時(shí)間也不再依靠表了,而今天的文章內(nèi)容就是與這類鐘表相關(guān);

環(huán)境配置
程序中用到的Python包
PyQt5
math
sys
實(shí)現(xiàn)思路
實(shí)現(xiàn)思路分為大致分為三個(gè)部分:老式鐘表制作、電子表制作、兩表合并為一個(gè)界面
老式鐘表制作
整體來(lái)看老式鐘表界面,有以下幾種圖案:時(shí)針、分針、秒針、1-12小時(shí)刻度、每格小刻度、每5格一大刻度

在鐘表運(yùn)行時(shí),時(shí)針、分針、秒針 隨時(shí)間變化以界面中心為圓點(diǎn)逆時(shí)針旋轉(zhuǎn)一定的角度,這個(gè)角度可以計(jì)算出來(lái)的
為了方便,整個(gè)界面效果我用 PyQt5 中的 QPainter 控件來(lái)實(shí)現(xiàn),這個(gè)控件其實(shí)就是一個(gè)繪制器,用來(lái)繪制界面上的元素
時(shí)鐘運(yùn)行軌跡其實(shí)就是把每一秒的畫(huà)面拼接在一起,最后組成一個(gè)連貫的時(shí)間序列圖像,因此重寫了 paintEvent 函數(shù),繪制每一秒實(shí)時(shí)圖像;
def paintEvent(self, event):
hour_points = [QPoint(5,8),QPoint(-5,8),QPoint(0,-30)]
minute_points = [QPoint(5,8),QPoint(-5,8),QPoint(0,-65)]
second_points = [QPoint(5,8),QPoint(-5,8),QPoint(0,-80)]
hour_color = QColor(200,100,0,200)
minute_color = QColor(0,127,127,150)
second_color = QColor(0,160,230,150)
min_len = min(self.width(),self.height())
time = QTime.currentTime() #獲取當(dāng)前時(shí)間
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.translate(self.width()/2,self.height()/2)#平移到窗口中心
painter.scale(min_len/200.0,min_len/200.0) #進(jìn)行尺度縮放
#----------繪制時(shí)針------------
painter.setPen(Qt.NoPen)
painter.setBrush(hour_color)#顏色
painter.save()
# 根據(jù) 1小時(shí)時(shí)= 30°,水品方向逆時(shí)針旋轉(zhuǎn)時(shí)針
painter.rotate(30.0*((time.hour()+time.minute()/60.0)))
painter.drawConvexPolygon(QPolygon(hour_points))
painter.restore() # save 退出,可重新設(shè)置畫(huà)筆
painter.setPen(hour_color)
#繪制小時(shí)線(360/12 = 30度)
for i in range(12):
painter.drawLine(88,0,96,0)#繪制水平線
painter.rotate(30.0)# 原有旋轉(zhuǎn)角度上進(jìn)行旋轉(zhuǎn);
radius = 100 # 半徑
font = painter.font()
font.setBold(True)
painter.setFont(font)
pointSize = font.pointSize()#字體大小
# print(pointSize)
#繪制小時(shí)文本
for i in range(12):
nhour = i + 3 # 從水平 3 點(diǎn)進(jìn)行繪制
if(nhour>12):
nhour -= 12
painter.drawText(self.textRectF(radius*0.8,pointSize,i*30),Qt.AlignCenter,str(nhour))
#繪制分針;
painter.setPen(Qt.NoPen)
painter.setBrush(minute_color)
painter.save()
# 1分鐘為6°,
painter.rotate(6.0*(time.minute()+time.second()/60.0))
painter.drawConvexPolygon(QPolygon(minute_points))
painter.restore()
#繪制分針線
painter.setPen(minute_color)
for i in range(60):
if(i%5 !=0):
painter.drawLine(92,0,96,0)
painter.rotate(6.0)
#繪制秒針
painter.setPen(Qt.NoPen)
painter.setBrush(second_color)
painter.save()
#繪制秒線
painter.rotate(6.0*time.second())
painter.drawConvexPolygon(QPolygon(second_points))
painter.restore()
painter.setPen(second_color)
for i in range(360):
if(i%5!=0 or i%30!=0):#繪制
painter.drawLine(94,0,96,0)
painter.rotate(1.0)#旋轉(zhuǎn)
再設(shè)置一個(gè)時(shí)間計(jì)時(shí)控件,利用信號(hào)槽機(jī)制連接界面,每一秒更新一次界面
self.timer = QTimer() # 定時(shí)器
self.timer.timeout.connect(self.update)
self.timer.start(1000) # 每1s 更新一次
電子表制作
電子表制作相對(duì)要比 老式鐘表制作 要簡(jiǎn)單地多,制作過(guò)程中用到 QLCDNumber 控件

QLDNumber 控件用來(lái)預(yù)覽數(shù)字,但上面的樣式讓數(shù)字看起來(lái)科技感更強(qiáng),作為電子表預(yù)覽是非常不錯(cuò)的選擇!

使用之前需對(duì)該控件的屬性做一下微調(diào),例如字體樣式,控件內(nèi)占據(jù)字符個(gè)數(shù)、邊框?qū)傩缘龋?/p>
self.lcdNumber = QtWidgets.QLCDNumber(Form)
self.lcdNumber.setGeometry(QtCore.QRect(0, 0, 250, 50))
self.lcdNumber.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
self.lcdNumber.setFrameShape(QtWidgets.QFrame.NoFrame)
self.lcdNumber.setSmallDecimalPoint(False)
self.lcdNumber.setDigitCount(8)
self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat)
self.lcdNumber.setProperty("value", 2021.0)
self.lcdNumber.setObjectName("lcdNumber")
電子表運(yùn)行效果也是借助于計(jì)時(shí)控件,每秒更新一次當(dāng)前界面的時(shí)間,但這里沒(méi)用到 QPainter
self.lcdNumber.display('00:00:00')
time_slot =QTimer(self)
# time_slot.setInterval(1000)
# time_slot.start()
time_slot.timeout.connect(self.event_1)
time_slot.start(1000)
def event_1(self):
time_format = QTime.currentTime()
time_format = time_format.toString("hh:mm:ss")
self.lcdNumber.display(time_format)
QApplication.processEvents()
合并兩表界面
兩個(gè)表界面創(chuàng)建完畢之后,最后用一個(gè) Widget 作為基類,利用 Qt 的水平布局把兩個(gè)表水平拼接在一起,形成了最終的效果

核心代碼
self.label1 = Clock_paint()
self.label2 = MyWidget()
self.horizon_layout = QHBoxLayout()
self.horizon_layout.addWidget(self.label1)
self.horizon_layout.addWidget(self.label2)
self.setLayout(self.horizon_layout)
self.setWindowTitle('時(shí)鐘--《公號(hào):小張Python》')
self.setWindowIcon(QIcon('clock.jpg'))
總結(jié)
本文中的案例算是 PyQt5 的一個(gè)小應(yīng)用,PyQt5 是 Qt 在 Python 語(yǔ)言中的封裝,制作 GUI界面時(shí) 個(gè)人非常推薦這個(gè)庫(kù),相對(duì)于 tk 我更喜歡前者,因?yàn)樗麲UI制作靈活性更強(qiáng),后續(xù)打算出更多小案例來(lái)介紹 PyQt5 的相關(guān)用法,敬請(qǐng)期待!
好了以上就是本篇文章的全部?jī)?nèi)容,最后感謝大家的閱讀,我們下期見(jiàn)~
希望大家以后多多支持腳本之家!
- Python PyQt5實(shí)戰(zhàn)項(xiàng)目之網(wǎng)速監(jiān)控器的實(shí)現(xiàn)
- Python實(shí)戰(zhàn)項(xiàng)目用PyQt5制作漫畫(huà)臉GUI界面
- Python編程使用PyQt5庫(kù)實(shí)現(xiàn)動(dòng)態(tài)水波進(jìn)度條示例
- 利用Python+PyQt5實(shí)現(xiàn)簡(jiǎn)易瀏覽器的實(shí)戰(zhàn)記錄
- Python PyQt5模塊實(shí)現(xiàn)一個(gè)瀏覽器的示例代碼
- Python PyQt5實(shí)戰(zhàn)項(xiàng)目之查詢器的實(shí)現(xiàn)流程詳解
相關(guān)文章
Python統(tǒng)計(jì)python文件中代碼,注釋及空白對(duì)應(yīng)的行數(shù)示例【測(cè)試可用】
這篇文章主要介紹了Python統(tǒng)計(jì)python文件中代碼,注釋及空白對(duì)應(yīng)的行數(shù),涉及Python針對(duì)py文件的讀取、遍歷、判斷、統(tǒng)計(jì)等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07
用Python實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)(附代碼)
這篇文章主要介紹了用Python實(shí)現(xiàn)BP神經(jīng)網(wǎng)絡(luò)(附代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Python 在區(qū)塊鏈智能合約開(kāi)發(fā)中的應(yīng)用與實(shí)踐小結(jié)
Python作為一種廣泛應(yīng)用的編程語(yǔ)言,在區(qū)塊鏈智能合約開(kāi)發(fā)中扮演著重要角色,通過(guò)使用Python框架如Brownie和Web3.py,開(kāi)發(fā)者可以輕松編寫和部署智能合約,感興趣的朋友一起看看吧2024-09-09
python下函數(shù)參數(shù)的傳遞(參數(shù)帶星號(hào)的說(shuō)明)
python中函數(shù)參數(shù)的傳遞是通過(guò)賦值來(lái)傳遞的。2010-09-09
python游戲的魅力之冒險(xiǎn)島實(shí)戰(zhàn)項(xiàng)目
我看了一眼沉迷《夢(mèng)幻國(guó)度》的兒子!氣就不打一處來(lái)!讓你見(jiàn)識(shí)一下Python游戲的魅力,python實(shí)戰(zhàn)冒險(xiǎn)島游戲碼起,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值2021-09-09

