一步一步教你用Python?pyglet仿制鴻蒙系統(tǒng)里的時(shí)鐘
鴻蒙時(shí)鐘
本篇將用python pyglet庫復(fù)刻華為手機(jī)鴻蒙系統(tǒng)鬧鐘程序的時(shí)鐘,先在上圖中抓取出時(shí)分秒針及刻度、表盤的顏色RGB值:
bHour = (42, 43, 48, 255)
bMinute = (70, 71, 75, 255)
rSecond = (240, 70, 20, 255)
gScale = 215, 220, 230
wBackground = 248, 250, 252
1. 繪制圓盤
首先要畫一圓Circle,并用直線Line等分成60份。
self.circle = pyglet.shapes.Circle(x, y, R, color=wBackground, batch=batch) self.scales = [pyglet.shapes.Line(x, y, x+R*cos(i*Pi/30), y+R*sin(i*Pi/30), width=2, color=gScales, batch=batch) for i in range(60)]
直線除圓心外的另一端點(diǎn)的坐標(biāo)計(jì)算公式,如下圖所示:
代碼:
import pyglet from math import pi, sin, cos window = pyglet.window.Window(800, 500, caption='圓盤') pyglet.gl.glClearColor(1, 1, 1, 1) batch = pyglet.graphics.Batch() R = 200 wBackground = 248, 250, 252 gScales = 215, 220, 230 class Watch: def __init__(self, x, y): self.circle = pyglet.shapes.Circle(x, y, R, color=wBackground, batch=batch) self.scales = [pyglet.shapes.Line(x, y, x+R*cos(i*pi/30), y+R*sin(i*pi/30), width=2, color=gScales, batch=batch) for i in range(60)] @window.event def on_draw(): window.clear() batch.draw() watch = Watch(window.width/2, window.height/2) pyglet.app.run()
2. 創(chuàng)建表類
改造這個(gè)Watch類,可設(shè)置圓心和半徑,并讓它成為pyglet.window.Window的子類。
import pyglet from math import sin, cos, pi wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='圓盤'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x, y, x+R*cos(i*pi/30), y+R*sin(i*pi/30), width=2, color=gScales, batch=self.batch) for i in range(60)] def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(500, 300, 150) watch.run()
3. 繪制刻度
擴(kuò)大圓面并縮短和加粗直線,表盤和刻度的大致輪廓就出現(xiàn)了。
代碼:
import pyglet from math import sin, cos, pi wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='刻度'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i, scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
4. 刻度數(shù)值
在整點(diǎn)的刻度值邊上用標(biāo)簽標(biāo)注上1~12的數(shù)字。
self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=24, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)+5, anchor_x='center', anchor_y='center', batch=self.batch) for i in range(12)]
代碼:
import pyglet from math import sin, cos, pi wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) rSecond = (240, 70, 20, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='指針'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i,scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=R*0.12, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)-R*0.06, anchor_x='center', batch=self.batch) for i in range(12)] def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
5. 添加指針
時(shí)、分、秒針,用三個(gè)圓三條直線來表示。
self.circle1 = pyglet.shapes.Circle(x, y, R*0.08, color=bHour) self.hour = pyglet.shapes.Line(x, y, x+R*0.7, y, width=9, color=bHour) self.minute = pyglet.shapes.Line(x, y, x+R*0.9, y, width=7, color=bMinute) self.second = pyglet.shapes.Line(x, y, x+R*1.1, y, width=5, color=rSecond) self.circle2 = pyglet.shapes.Circle(x, y, R*0.05, color=rSecond) self.circle3 = pyglet.shapes.Circle(x, y, R*0.02, color=wWhite)
不用擔(dān)心秒針長過表盤圓面,轉(zhuǎn)動(dòng)前會(huì)作“移動(dòng)”處理。
代碼:
import pyglet from math import sin, cos, pi wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) rSecond = (240, 70, 20, 255) bMinute = (70, 71, 75, 255) bHour = (42, 43, 48, 255) wWhite = (255, 255, 255, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='指針'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i,scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=R*0.12, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)-R*0.06, anchor_x='center', batch=self.batch) for i in range(12)] self.circle1 = pyglet.shapes.Circle(x, y, R*0.08, color=bHour, batch=self.batch) self.hour = pyglet.shapes.Line(x, y, x+R*0.7, y, width=9, color=bHour, batch=self.batch) self.minute = pyglet.shapes.Line(x, y, x+R*0.9, y, width=7, color=bMinute, batch=self.batch) self.second = pyglet.shapes.Line(x, y, x+R*1.1, y, width=5, color=rSecond, batch=self.batch) self.circle2 = pyglet.shapes.Circle(x, y, R*0.05, color=rSecond, batch=self.batch) self.circle3 = pyglet.shapes.Circle(x, y, R*0.02, color=wWhite, batch=self.batch) def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
6. 轉(zhuǎn)動(dòng)指針
時(shí)、分、秒針的轉(zhuǎn)動(dòng)運(yùn)用Line控件的旋轉(zhuǎn)屬性.rotation,這種方法要比修改端點(diǎn)坐標(biāo)要方便。
默認(rèn)的旋轉(zhuǎn)中心是直線的左端點(diǎn),屬性.anchor_position可以修改中心坐標(biāo)。
self.second.anchor_position = (R*0.1, 0) self.second.rotation = 210 self.minute.rotation = 24 self.hour.rotation = 160
代碼:
import pyglet from math import sin, cos, pi wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) rSecond = (240, 70, 20, 255) bMinute = (70, 71, 75, 255) bHour = (42, 43, 48, 255) wWhite = (255, 255, 255, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='指針'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i,scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=R*0.12, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)-R*0.06, anchor_x='center', batch=self.batch) for i in range(12)] self.circle1 = pyglet.shapes.Circle(x, y, R*0.08, color=bHour, batch=self.batch) self.hour = pyglet.shapes.Line(x, y, x+R*0.7, y, width=9, color=bHour, batch=self.batch) self.minute = pyglet.shapes.Line(x, y, x+R*0.9, y, width=7, color=bMinute, batch=self.batch) self.second = pyglet.shapes.Line(x, y, x+R*1.1, y, width=5, color=rSecond, batch=self.batch) self.circle2 = pyglet.shapes.Circle(x, y, R*0.05, color=rSecond, batch=self.batch) self.circle3 = pyglet.shapes.Circle(x, y, R*0.02, color=wWhite, batch=self.batch) self.second.anchor_position = (R*0.1, 0) self.second.rotation = 210 self.minute.rotation = 24 self.hour.rotation = 160 def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
7. 聯(lián)動(dòng)時(shí)間
聯(lián)動(dòng)系統(tǒng)時(shí)鐘,使用datetime.now()獲取當(dāng)前時(shí)間的時(shí)、分、秒的值。
now = datetime.now() h, m, s = now.hour, now.minute, now.second self.second.rotation = -90 + s*6 self.minute.rotation = -90 + m*6 + s/10 self.hour.rotation = -90 + h%12*30 + m/2
代碼:
import pyglet from math import sin, cos, pi from datetime import datetime wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) rSecond = (240, 70, 20, 255) bMinute = (70, 71, 75, 255) bHour = (42, 43, 48, 255) wWhite = (255, 255, 255, 255) class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='指針'): super().__init__(width, height, caption=caption) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i,scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=R*0.12, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)-R*0.06, anchor_x='center', batch=self.batch) for i in range(12)] self.circle1 = pyglet.shapes.Circle(x, y, R*0.08, color=bHour, batch=self.batch) self.hour = pyglet.shapes.Line(x, y, x+R*0.7, y, width=9, color=bHour, batch=self.batch) self.minute = pyglet.shapes.Line(x, y, x+R*0.9, y, width=7, color=bMinute, batch=self.batch) self.second = pyglet.shapes.Line(x, y, x+R*1.1, y, width=5, color=rSecond, batch=self.batch) self.circle2 = pyglet.shapes.Circle(x, y, R*0.05, color=rSecond, batch=self.batch) self.circle3 = pyglet.shapes.Circle(x, y, R*0.02, color=wWhite, batch=self.batch) self.second.anchor_position = (R*0.1, 0) self.update() def update(self): now = datetime.now() h, m, s = now.hour, now.minute, now.second self.second.rotation = -90 + s*6 self.minute.rotation = -90 + m*6 + s/10 self.hour.rotation = -90 + h%12*30 + m/2 def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
8. 運(yùn)行時(shí)鐘
使用pyglet.clock.schedule_interval(self.update, 0.2)每秒更新5次。
總得來說,本次復(fù)刻比較完美,但直線控件在非水平或垂直狀態(tài),特別是小夾角時(shí)鋸齒很嚴(yán)重。
完整代碼:
import pyglet from math import sin, cos, pi from datetime import datetime class Watch(pyglet.window.Window): def __init__(self, x, y, R=200, width=800, height=500, caption='時(shí)鐘'): super().__init__(width, height, caption=caption) wBackground = (248, 250, 252, 255) gScales = (215, 220, 230, 255) rSecond = (240, 70, 20, 255) bMinute = (70, 71, 75, 255) bHour = (42, 43, 48, 255) wWhite = (255, 255, 255, 255) pyglet.gl.glClearColor(1, 1, 1, 1) self.batch = pyglet.graphics.Batch() self.circle = pyglet.shapes.Circle(x, y, R*1.05, color=wBackground, batch=self.batch) self.scales = [pyglet.shapes.Line(x+R*cos(i*pi/30), y+R*sin(i*pi/30), x+R*0.95*cos(i*pi/30), y+0.95*R*sin(i*pi/30), width=3, color=gScales, batch=self.batch) for i in range(60)] for i,scale in enumerate(self.scales): if i%5==0: scale.width, scale.x2, scale.y2 = 5, x+R*0.92*cos(i*pi/30), y+0.92*R*sin(i*pi/30) self.labels = [pyglet.text.Label(str((2-i)%12+1), font_size=R*0.12, color=(0,0,0,255), x=x+R*0.82*cos(i*pi/6), y=y+0.82*R*sin(i*pi/6)-R*0.06, anchor_x='center', batch=self.batch) for i in range(12)] self.circle1 = pyglet.shapes.Circle(x, y, R*0.08, color=bHour, batch=self.batch) self.hour = pyglet.shapes.Line(x, y, x+R*0.7, y, width=9, color=bHour, batch=self.batch) self.minute = pyglet.shapes.Line(x, y, x+R*0.9, y, width=7, color=bMinute, batch=self.batch) self.second = pyglet.shapes.Line(x, y, x+R*1.1, y, width=5, color=rSecond, batch=self.batch) self.circle2 = pyglet.shapes.Circle(x, y, R*0.05, color=rSecond, batch=self.batch) self.circle3 = pyglet.shapes.Circle(x, y, R*0.02, color=wWhite, batch=self.batch) self.second.anchor_position = (R*0.1, 0) self.update(self.event) pyglet.clock.schedule_interval(self.update, 0.2) def update(self, event): now = datetime.now() h, m, s = now.hour, now.minute, now.second self.second.rotation = -90 + s*6 self.minute.rotation = -90 + m*6 + s/10 self.hour.rotation = -90 + h%12*30 + m/2 def on_draw(self): self.clear() self.batch.draw() def run(self): pyglet.app.run() watch = Watch(400, 250) watch.run()
完
總結(jié)
到此這篇關(guān)于一步一步教你用Python pyglet仿制鴻蒙系統(tǒng)里的時(shí)鐘的文章就介紹到這了,更多相關(guān)Python pyglet仿鴻蒙的時(shí)鐘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python Django連接MySQL數(shù)據(jù)庫做增刪改查
本文寫的是python Django連接MySQL數(shù)據(jù)庫的步驟,提供增刪改查的代碼2013-11-11分析機(jī)器學(xué)習(xí)之決策樹Python實(shí)現(xiàn)
決策樹是一種非參數(shù)的有監(jiān)督學(xué)習(xí)方法,它能夠從一系列有特征和標(biāo)簽的數(shù)據(jù)中總結(jié)出決策規(guī)則,并用樹狀圖的結(jié)構(gòu)來呈現(xiàn)這些規(guī)則,以解決分類和回歸問題。決策樹算法容易理解,適用各種數(shù)據(jù),在解決各種問題時(shí)都有良好表現(xiàn)2021-06-06linux系統(tǒng)使用python監(jiān)測系統(tǒng)負(fù)載腳本分享
這篇文章主要介紹了linux系統(tǒng)使用python監(jiān)測系統(tǒng)負(fù)載腳本,大家參考使用吧2014-01-01Pandas的Series結(jié)構(gòu)及常用操作實(shí)例
這篇文章主要介紹了Pandas的Series結(jié)構(gòu)及常用操作實(shí)例,Series序列,是一種一維的結(jié)構(gòu),類似于一維列表和ndarray中的一維數(shù)組,但是功能比他們要更為強(qiáng)大,Series由兩部分組成:索引index和數(shù)值values,需要的朋友可以參考下2023-07-07使用python搭建代理IP池實(shí)現(xiàn)接口設(shè)置與整體調(diào)度
在網(wǎng)絡(luò)爬蟲中,代理IP池是一個(gè)非常重要的組件,由于許多網(wǎng)站對單個(gè)IP的請求有限制,因此,我們需要一個(gè)代理IP池,在本文中,我們將使用Python來構(gòu)建一個(gè)代理IP池,然后,我們將使用這個(gè)代理IP池來訪問我們需要的數(shù)據(jù),文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12