Maix Dock使用MaixUI——canvas(四)

说明

这里着重介绍一下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()函数中体现出来。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值