问题描述
我用lvgl做应用,发现闪屏很严重,在IDE上和液晶屏上都会闪屏,我把代码发上来,帮我看一下是什么问题,我发了一个你们可以直接运行的代码。
复现步骤
import time
import lvgl as lv
import uctypes
from media.display import *
from media.media import *
print("=== LVGL 闪屏测试程序 (官方版) ===")
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 480
虚拟显示
Display.init(Display.VIRT, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT, to_ide=True)
lv.init()
双缓冲
disp_imgs = [image.Image(DISPLAY_WIDTH, DISPLAY_HEIGHT, image.RGB565) for _ in range(2)]
disp_drv = lv.disp_create(DISPLAY_WIDTH, DISPLAY_HEIGHT)
disp_drv.set_color_format(lv.COLOR_FORMAT.RGB565)
disp_drv.set_draw_buffers(disp_imgs[0].bytearray(), disp_imgs[1].bytearray(),
disp_imgs[0].size(), lv.DISP_RENDER_MODE.FULL)
def flush_cb(disp_drv, area, color):
if disp_drv.flush_is_last():
ptr = uctypes.addressof(color.dereference())
for img in disp_imgs:
if img.virtaddr() == ptr:
Display.show_image(img)
break
disp_drv.flush_ready()
disp_drv.set_flush_cb(flush_cb)
模拟触摸输入(不依赖硬件)
class SimTouch:
def init(self):
self.indev = lv.indev_create()
self.indev.set_type(lv.INDEV_TYPE.POINTER)
self.indev.set_read_cb(self.callback)
self.pressed = False
self.x = 0
self.y = 0
def callback(self, driver, data):
data.point.x = self.x
data.point.y = self.y
data.state = lv.INDEV_STATE.PRESSED if self.pressed else lv.INDEV_STATE.RELEASED
def set_touch(self, x, y, pressed):
self.x = x
self.y = y
self.pressed = pressed
sim_touch = SimTouch()
主屏幕
scr = lv.scr_act()
scr.set_style_bg_color(lv.color_hex(0x1A2A3A), 0)
标题
title = lv.label(scr)
title.set_text("LVGL Flicker Test")
title.set_style_text_color(lv.color_hex(0xFFFFFF), 0)
title.align(lv.ALIGN.TOP_MID, 0, 20)
创建 6 个卡片
cards = []
card_colors = [0x2A3A4A, 0x3A4A5A, 0x4A5A6A, 0x5A6A7A, 0x6A7A8A, 0x7A8A9A]
for i in range(6):
card = lv.obj(scr)
card.set_size(220, 160)
card.set_pos(40 + (i % 3) * 260, 70 + (i // 3) * 190)
card.set_style_bg_color(lv.color_hex(card_colors[i]), 0)
card.set_style_radius(10, 0)
temp_label = lv.label(card)
temp_label.set_text("45.2°C")
temp_label.set_style_text_color(lv.color_hex(0x00FF00), 0)
temp_label.align(lv.ALIGN.CENTER, 0, -20)
target_label = lv.label(card)
target_label.set_text("Target: 100°C")
target_label.set_style_text_color(lv.color_hex(0xAAAAAA), 0)
target_label.align(lv.ALIGN.CENTER, 0, 20)
cards.append(temp_label)
创建进度条
bar = lv.bar(scr)
bar.set_size(300, 20)
bar.align(lv.ALIGN.BOTTOM_MID, 0, -50)
bar.set_range(0, 100)
创建按钮
btn = lv.btn(scr)
btn.set_size(120, 50)
btn.align(lv.ALIGN.BOTTOM_RIGHT, -20, -50)
btn_label = lv.label(btn)
btn_label.set_text("Click")
btn_label.center()
def btn_cb(evt):
if evt.get_code() == lv.EVENT.CLICKED:
print("Button clicked")
btn.add_event(btn_cb, lv.EVENT.CLICKED, None)
print("开始测试,数据每 0.5 秒更新一次")
print("观察 IDE 显示窗口是否有闪屏现象")
print("可用鼠标点击按钮测试交互")
count = 0
last_update = time.ticks_ms()
模拟鼠标移动
mouse_x = 400
mouse_y = 300
mouse_dir = 1
while True:
lv.timer_handler()
# 模拟鼠标移动(测试刷新)
mouse_x += mouse_dir * 10
if mouse_x > 700 or mouse_x < 100:
mouse_dir = -mouse_dir
sim_touch.set_touch(mouse_x, mouse_y, False)
now = time.ticks_ms()
if now - last_update > 500:
# 更新所有卡片温度
for i, label in enumerate(cards):
val = 45 + (count % 50) / 10
label.set_text(f"{val:.1f}°C")
# 更新进度条
bar.set_value(count % 101, lv.ANIM.OFF)
count += 1
last_update = now
time.sleep_ms(20)