说明
这里着重介绍一下ui.cavias,这一块是比较复杂的,但直接关系着界面的展示。
import image, lcd, math, gc, random, os
# gc.collect()
lcd.init(freq=15000000)
def print_mem_free():
print('ram total : ' + str(gc.mem_free() / 1024) + ' kb')
class ui:
alpha, img, anime, bak = 0, None, None, None
bg_path = os.getcwd() + "/res/images/bg.jpg"
logo_path = os.getcwd() + "/res/images/logo.jpg"
height, weight = lcd.height(), lcd.width()
enable = True
def warp_template(func):
def tmp_warp(warp=None):
if warp:
return lambda *args: [func(), warp()]
return tmp_warp
def blank_draw():
if ui.enable:
ui.canvas = image.Image(size=(ui.height, ui.weight)
) # 10ms # 168.75kb (112kb)
def grey_draw():
if ui.enable:
ui.canvas.draw_rectangle((0, 0, ui.height, ui.weight),
fill=True, color=(75, 75, 75))
def bg_in_draw():
if ui.enable:
#ui.canvas.draw_rectangle((0, 0, ui.height, ui.weight),
#fill=True, color=(75, 75, 75))
#if ui.bak == None:
#ui.bak.draw_rectangle((60,30,120,150), fill=True, color=(250, 0, 0))
#ui.bak.draw_string(70, 40, "o", color=(255, 255, 255), scale=2)
#ui.bak.draw_string(80, 10, "s", color=(255, 255, 255), scale=15)
ui.canvas.draw_circle(121, 111, int(50),
color=(64, 64, 64), thickness=3) # 10ms
ui.canvas.draw_circle(120, 110, int(50),
color=(250, 0, 0)) # 10ms
ui.canvas.draw_circle(120, 110, int(50), fill=True,
color=(250, 0, 0)) # 10ms
sipeed = b'\x40\xA3\x47\x0F\x18\x38\x18\x0F\x07\x03\x00\x00\x00\x0F\x0F\x0F\x00\xFC\xFC\xFC\x00\x00\x00\xF0\xF8\xFC\x06\x07\x06\xFC\xF8\xF0'
ui.canvas.draw_font(88, 80, 16, 16, sipeed, scale=4, color=(64,64,64))
ui.canvas.draw_font(86, 78, 16, 16, sipeed, scale=4, color=(255,255,255))
# ui.canvas = ui.canvas # 15ms
#ui.canvas = ui.bak.copy() # 10ms 282kb
def bg_draw():
if ui.enable:
if ui.bak == None:
ui.bak = image.Image(ui.bg_path) # 90ms
ui.canvas.draw_image(ui.bak, 0, 0) # 20ms
def help_in_draw():
if ui.enable:
ui.canvas.draw_string(30, 6, "<", (255, 0, 0), scale=2)
ui.canvas.draw_string(60, 6, "ENTER/HOME", (255, 0, 0), scale=2)
ui.canvas.draw_string(200, 6, ">", (255, 0, 0), scale=2)
ui.canvas.draw_string(10, ui.height - 30,
"RESET", (255, 0, 0), scale=2)
ui.canvas.draw_string(178, ui.height - 30,
"POWER", (255, 0, 0), scale=2)
def anime_draw(alpha=None):
if ui.enable:
if alpha == None:
alpha = math.cos(math.pi * ui.alpha / 32) * 80 + 170
ui.alpha = (ui.alpha + 1) % 64
if ui.anime == None:
ui.anime = image.Image(ui.logo_path) # 90ms
ui.canvas.draw_image(ui.anime, 70, 70, alpha=int(alpha)) # 15ms
def anime_in_draw(alpha=None):
if ui.enable:
if alpha == None:
alpha = math.cos(math.pi * ui.alpha / 100) * 200
ui.alpha = (ui.alpha + 1) % 200
r, g, b = random.randint(120, 255), random.randint(
120, 255), random.randint(120, 255)
ui.canvas.draw_circle(0, 0, int(alpha), color=(
r, g, b), thickness=(r % 5)) # 10ms
ui.canvas.draw_circle(0, 0, 200 - int(alpha),
color=(r, g, b), thickness=(g % 5)) # 10ms
ui.canvas.draw_circle(240, 0, int(alpha), color=(
r, g, b), thickness=(b % 5)) # 10ms
ui.canvas.draw_circle(240, 0, 200 - int(alpha),
color=(r, g, b), thickness=(r % 5)) # 10ms
ui.canvas.draw_circle(0, 240, int(alpha), color=(
r, g, b), thickness=(g % 5)) # 10ms
ui.canvas.draw_circle(0, 240, 200 - int(alpha),
color=(r, g, b), thickness=(b % 5)) # 10ms
ui.canvas.draw_circle(240, 240, int(alpha), color=(
r, g, b), thickness=(r % 5)) # 10ms
ui.canvas.draw_circle(240, 240, 200 - int(alpha),
color=(r, g, b), thickness=(g % 5)) # 10ms
def display(): # 10ms
try:
if ui.canvas != None:
lcd.display(ui.canvas)
finally:
try:
if ui.canvas != None:
tmp = ui.canvas
ui.canvas = None
del tmp
except Exception as e:
pass
# gc.collect()
if __name__ == "__main__":
# ui.height, ui.weight = 480, 320 # amigo
#@ui.warp_template(ui.blank_draw)
#@ui.warp_template(ui.bg_draw)
#@ui.warp_template(ui.anime_draw)
# 50ms
@ui.warp_template(ui.blank_draw)
#@ui.warp_template(ui.grey_draw)
@ui.warp_template(ui.bg_in_draw)
#@ui.warp_template(ui.anime_in_draw)
#@ui.warp_template(ui.help_in_draw)
# 20ms
def test_launcher_draw():
#ui.bg_draw()
ui.display()
import time
last = time.ticks_ms()
while True:
try:
print(time.ticks_ms() - last)
last = time.ticks_ms()
# gc.collect()
test_launcher_draw()
except Exception as e:
print(e)
cavas开始一些
lcd.init(freq=15000000)
def print_mem_free():
print('ram total : ' + str(gc.mem_free() / 1024) + ' kb')
这里初始化一下lcd的频率,通过官网的文档,我们可以了解到,k210和lcd是通过spi通信实现的,这里的频率设定其实就是对spi通信时钟的设置。
频率设置上同时释放内存,因为是mcu,所拥有的ram资源有限。为了更好显示,必须先清空所有ram的空间,方便接下来lcd数据的缓存。
UI类的说明
这里面主要的类是ui类,里面的方法warp_template重要的方法 还有一个最关键的display。
其他的都是一些样式UI的方法blank_draw() grey_draw() bg_in_draw bg_draw help_in_draw anime_draw anime_in_draw 。接下来我们逐个分析一下这些代码。
ui内部变量
alpha, img, anime, bak = 0, None, None, None
bg_path = os.getcwd() + "/res/images/bg.jpg"
logo_path = os.getcwd() + "/res/images/logo.jpg"
height, weight = lcd.height(), lcd.width()
enable = True
先做好背景图和logo图的资源,且把lcd的高宽赋值,并激活变量,供其他的函数使用。
warp_template
def warp_template(func):
def tmp_warp(warp=None):
if warp:
return lambda *args: [func(), warp()]
return tmp_warp
直接判断warp是否有数据,如果有数据就返回args 函数。lambda函数的介绍
当看到warp ,我们通过vs code 查找一下,发现在warp是在ui_catch里面定义的,具体代码如下:
def catch(func):
def warp(warp=None):
try:
func()
except Exception as e:
try:
btn = sipeed_button()
import uio
string_io = uio.StringIO()
sys.print_exception(e, string_io)
s = string_io.getvalue()
ui.canvas.draw_rectangle(
(10, 10, ui.height - 20, ui.weight - 20), fill=True, color=(50, 50, 50))
msg = "** " + str(e)
chunks, chunk_size = len(msg), 29
msg_lines = [msg[i:i+chunk_size]
for i in range(0, chunks, chunk_size)]
x_offset, y_offset = 10 + 5, 20
ui.canvas.draw_string(
x_offset + 24, y_offset + 5, "A problem has been detected", color=(0, 255, 0))
ui.canvas.draw_string(
x_offset + 3, y_offset + 16, "------------------------------", (255, 255, 255))
current_y = y_offset + 10 + 5 + 16
for line in msg_lines:
ui.canvas.draw_string(x_offset, current_y,
line, color=(255, 0, 0))
current_y += 16
if current_y >= ui.canvas.height():
break
ui.canvas.draw_string(
x_offset, y_offset + current_y, s, color=(0, 255, 0))
lcd.display(ui.canvas)
happen = time.ticks_ms()
while (happen + 5000) > time.ticks_ms():
info = "(%d)" % (
5 - (int)(time.ticks_ms() - happen) / 1000)
btn.event()
if btn.back() == 2 or btn.home() == 2 or btn.next() == 2:
break
ui.canvas.draw_rectangle(
(x_offset, y_offset + 5, len(info) * 8, 12), fill=True, color=(50, 50, 50))
ui.canvas.draw_string(
x_offset, y_offset + 5, info, color=(0, 255, 0))
lcd.display(ui.canvas)
time.sleep_ms(100)
ui.display()
# gc.collect()
except Exception as e:
print(e)
return warp
我们在main.py函数中可以看到,@函数装饰符 参考 其实简单的理解就是将ui内的样式内容,引到warp_template函数中去。在warp_template的func()函数中体现出来。