一步一步教你用Python?pyglet仿制鴻蒙系統(tǒng)里的時鐘

鴻蒙時鐘
本篇將用python pyglet庫復(fù)刻華為手機(jī)鴻蒙系統(tǒng)鬧鐘程序的時鐘,先在上圖中抓取出時分秒針及刻度、表盤的顏色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)]直線除圓心外的另一端點的坐標(biāo)計算公式,如下圖所示:

代碼:
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)建表類
改造這個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ù)值
在整點的刻度值邊上用標(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. 添加指針
時、分、秒針,用三個圓三條直線來表示。
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)動前會作“移動”處理。

代碼:
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)動指針
時、分、秒針的轉(zhuǎn)動運用Line控件的旋轉(zhuǎn)屬性.rotation,這種方法要比修改端點坐標(biāo)要方便。
默認(rèn)的旋轉(zhuǎ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)動時間
聯(lián)動系統(tǒng)時鐘,使用datetime.now()獲取當(dāng)前時間的時、分、秒的值。
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. 運行時鐘
使用pyglet.clock.schedule_interval(self.update, 0.2)每秒更新5次。
總得來說,本次復(fù)刻比較完美,但直線控件在非水平或垂直狀態(tài),特別是小夾角時鋸齒很嚴(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='時鐘'):
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)里的時鐘的文章就介紹到這了,更多相關(guān)Python pyglet仿鴻蒙的時鐘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python Django連接MySQL數(shù)據(jù)庫做增刪改查
本文寫的是python Django連接MySQL數(shù)據(jù)庫的步驟,提供增刪改查的代碼2013-11-11
分析機(jī)器學(xué)習(xí)之決策樹Python實現(xiàn)
決策樹是一種非參數(shù)的有監(jiān)督學(xué)習(xí)方法,它能夠從一系列有特征和標(biāo)簽的數(shù)據(jù)中總結(jié)出決策規(guī)則,并用樹狀圖的結(jié)構(gòu)來呈現(xiàn)這些規(guī)則,以解決分類和回歸問題。決策樹算法容易理解,適用各種數(shù)據(jù),在解決各種問題時都有良好表現(xiàn)2021-06-06
linux系統(tǒng)使用python監(jiān)測系統(tǒng)負(fù)載腳本分享
這篇文章主要介紹了linux系統(tǒng)使用python監(jiān)測系統(tǒng)負(fù)載腳本,大家參考使用吧2014-01-01
Pandas的Series結(jié)構(gòu)及常用操作實例
這篇文章主要介紹了Pandas的Series結(jié)構(gòu)及常用操作實例,Series序列,是一種一維的結(jié)構(gòu),類似于一維列表和ndarray中的一維數(shù)組,但是功能比他們要更為強(qiáng)大,Series由兩部分組成:索引index和數(shù)值values,需要的朋友可以參考下2023-07-07
使用python搭建代理IP池實現(xiàn)接口設(shè)置與整體調(diào)度
在網(wǎng)絡(luò)爬蟲中,代理IP池是一個非常重要的組件,由于許多網(wǎng)站對單個IP的請求有限制,因此,我們需要一個代理IP池,在本文中,我們將使用Python來構(gòu)建一個代理IP池,然后,我們將使用這個代理IP池來訪問我們需要的數(shù)據(jù),文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2023-12-12

