目錄
鴻蒙時鐘
1. 繪制圓盤
2. 創(chuàng)建表類
3. 繪制刻度
4. 刻度數(shù)值
5. 添加指針
6. 轉(zhuǎn)動指針
7. 聯(lián)動時間
8. 時鐘走動
鴻蒙時鐘
本篇將用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)]
直線除圓心外的另一端點(diǎn)的坐標(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ù)值
在整點(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. 添加指針
時、分、秒針,用三個圓三條直線來表示。
? ? ? ? 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)動運(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)動時間
聯(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. 運(yùn)行時鐘
使用pyglet.clock.schedule_interval(self.update, 0.2)每秒更新5次。
總得來說,本次復(fù)刻比較完美,但直線控件在非水平或垂直狀態(tài),特別是小夾角時鋸齒很嚴(yán)重。
完整代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-838825.html
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()
完文章來源地址http://www.zghlxwxcb.cn/news/detail-838825.html
到了這里,關(guān)于Python 一步一步教你用pyglet仿制鴻蒙系統(tǒng)里的時鐘的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!