多分辨率 LCD 的 GUI 架构设计与实现
1.1多分辨率显示系统的挑战与解决方案
1.1.1 分辨率适配的核心问题
在嵌入式系统中,同时支持不同分辨率的 LCD(如 240×160、320×480 等)面临以下挑战:
布局适配:同一界面元素在不同分辨率下需要调整大小和位置
字体显示:小分辨率屏幕需要更小的字体,而大分辨率需要更清晰的字体
内存占用:高分辨率屏幕需要更多显存,而低分辨率需要优化内存使用
渲染性能:高分辨率屏幕渲染压力更大,需要优化渲染算法
针对这些问题, 采用以下解决方案:
抽象显示接口:定义统一的显示操作接口,屏蔽底层硬件差异
相对布局系统:使用百分比或相对单位定义界面元素位置和大小
字体动态缩放:根据屏幕分辨率动态调整字体大小
资源按需加载:根据当前屏幕分辨率选择合适的图片和字体资源
1.1.2 单色屏与彩屏的兼容性设计
同时支持单色屏和彩屏时,需要解决以下问题:
颜色表示:单色屏只有黑白两色,而彩屏支持多种颜色
图形渲染:彩屏支持渐变、阴影等复杂效果,单色屏需要简化
交互反馈:彩屏可通过颜色变化提供反馈,单色屏需依赖对比度或闪烁
解决方案包括:
颜色抽象层:定义颜色映射表,将 RGB 颜色映射到单色屏的黑白值
渲染策略分离:为单色屏和彩屏分别实现不同的渲染算法
交互反馈统一:使用统一的交互反馈接口,底层根据屏幕类型实现
1.2 统一显示抽象层设计
1.2.1 显示接口定义
我们首先定义一个抽象的显示接口,屏蔽不同分辨率和类型的 LCD 差异:
c
/**
* 显示抽象层接口定义
* 支持不同分辨率和类型的LCD
*/
#ifndef DISPLAY_ABSTRACTION_H
#define DISPLAY_ABSTRACTION_H
#include <stdint.h>
#include <stdbool.h>
/* 颜色定义 - 采用RGB565格式 */
typedef uint16_t color_t;
/* 标准颜色常量 */
#define COLOR_BLACK 0x0000
#define COLOR_WHITE 0xFFFF
#define COLOR_RED 0xF800
#define COLOR_GREEN 0x07E0
#define COLOR_BLUE 0x001F
#define COLOR_YELLOW 0xFFE0
#define COLOR_CYAN 0x07FF
#define COLOR_MAGENTA 0xF81F
/* 显示区域结构体 */
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} rect_t;
/* 显示设备能力结构体 */
typedef struct
{
uint16_t width; /* 屏幕宽度 */
uint16_t height; /* 屏幕高度 */
uint8_t bits_per_pixel; /* 每像素位数 */
bool color_support; /* 是否支持彩色 */
uint16_t max_font_size; /* 最大支持字体大小 */
uint16_t min_font_size; /* 最小支持字体大小 */
} display_capabilities_t;
/* 显示接口函数指针结构体 */
typedef struct
{
/* 基本操作 */
void (*init)(void);
void (*clear)(color_t color);
void (*refresh)(void);
/* 绘制基本图形 */
void (*draw_pixel)(uint16_t x, uint16_t y, color_t color);
void (*draw_line)(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, color_t color);
void (*draw_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*fill_rect)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, color_t color);
void (*draw_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
void (*fill_circle)(uint16_t x, uint16_t y, uint16_t radius, color_t color);
/* 文本绘制 */
void (*set_font_size)(uint8_t size);
void (*set_text_color)(color_t color, color_t background);
void (*draw_char)(uint16_t x, uint16_t y, char c);
void (*draw_string)(uint16_t x, uint16_t y, const char* str);
/* 图像绘制 */
void (*draw_image)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint16_t* data);
/* 获取显示能力 */
void (*get_capabilities)(display_capabilities_t* caps);
} display_interface_t;
/* 获取当前显示接口实例 */
display_interface_t* get_display_interface(void);
/* 设置当前显示接口实例 */
void set_display_interface(display_interface_t* display);
#endif /* DISPLAY_ABSTRACTION_H */
1.2.2 显示接口实现
下面是显示接口的基础实现,提供了统一的操作入口:
/**
* 显示抽象层实现
*/
#include "display_abstraction.h"
/* 当前显示接口实例 */
static display_interface_t* current_display = NULL;
/* 获取当前显示接口实例 */
display_interface_t* get_display_interface(void)
{
return current_display;
}
/* 设置当前显示接口实例 */
void set_display_interface(display_interface_t* display)
{
current_display = display;
}
/* 通用绘制函数 - 使用当前显示接口 */
void display_clear(color_t color)
{
if (current_display && current_display->clear)
{
current_display->clear(color);
}
}
void display_refresh(void)
{
if (current_display && current_display->refresh)
{
current_display->refresh();
}
}
void display_draw_pixel(uint16_t x, uint16_t y, color_t color)
{
if (current_display && current_display->draw_pixel)
{
current_display->draw_pixel(x, y, color);
}
}
// 其他通用绘制函数实现...
1.3 相对布局系统设计
1.3.1 布局管理器设计
为了实现跨分辨率的 GUI 适配,我们设计一个相对布局管理器:
/**
* 相对布局管理器
* 支持基于百分比的界面元素布局
*/
#ifndef LAYOUT_MANAGER_H
#define LAYOUT_MANAGER_H
#include "display_abstraction.h"
/* 对齐方式枚举 */
typedef enum
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT,
ALIGN_TOP,
ALIGN_MIDDLE,
ALIGN_BOTTOM
} alignment_t;
/* 相对位置结构体 */
typedef struct
{
float x_percent; /* X坐标百分比 (0.0-1.0) */
float y_percent; /* Y坐标百分比 (0.0-1.0) */
float width_percent; /* 宽度百分比 (0.0-1.0) */
float height_percent; /* 高度百分比 (0.0-1.0) */
alignment_t h_align; /* 水平对齐方式 */
alignment_t v_align; /* 垂直对齐方式 */
} relative_position_t;
/* GUI元素基类 */
typedef struct gui_element
{
char* id; /* 元素ID */
relative_position_t position; /* 相对位置 */
bool visible; /* 是否可见 */
/* 绘制函数 */
void (*draw)(struct gui_element* element);
/* 事件处理函数 */
bool (*handle_event)(struct gui_element* element, void* event);
/* 布局计算函数 */
void (*calculate_layout)(struct gui_element* element, rect_t* parent_rect);
/* 实际屏幕位置 */
rect_t screen_rect;
/* 指向下一个元素的指针 */
struct gui_element* next;
} gui_element_t;
/* 布局管理器 */
typedef struct
{
gui_element_t* elements; /* 元素链表 */
display_interface_t* display; /* 显示接口 */
rect_t root_rect; /* 根区域 */
} layout_manager_t;
/* 初始化布局管理器 */
void layout_manager_init(layout_manager_t* manager, display_interface_t* display);
/* 添加GUI元素 */
void layout_manager_add_element(layout_manager_t* manager, gui_element_t* element);
/* 移除GUI元素 */
void layout_manager_remove_element(layout_manager_t* manager, gui_element_t*
相关文章:
多分辨率 LCD 的 GUI 架构设计与实现
1.1多分辨率显示系统的挑战与解决方案 1.1.1 分辨率适配的核心问题 在嵌入式系统中,同时支持不同分辨率的 LCD(如 240160、320480 等)面临以下挑战: 布局适配:同一界面元素在不同分辨率下需要调整大小和位置 字体显示:小分辨率屏幕需要更小的字体,而大分辨率需要更清…...

2025年,百度智能云打响AI落地升维战
如果说从AI到Agent是对于产品落地形态的共识,那么如今百度智能云打响的恰是一个基于Agent进行TO B行业表达的AI生产力升维战。 在这个新的工程体系能力里,除了之前百度Create大会上提出的面向Agent的RAG能力等通用能力模块,对更为专业、个性…...

Seed1.5-VL登顶,国产闭源模型弯道超车丨多模态模型5月最新榜单揭晓
随着图像、文本、语音、视频等多模态信息融合能力的持续增强,多模态大模型在感知理解、逻辑推理和内容生成等任务中的综合表现不断提升,正在展现出愈发接近人类的智能水平。多模态能力也正在从底层的感知理解,迈向具备认知、推理、决策能力的…...
SON.stringify()和JSON.parse()之间的转换
1.JSON.stringify() 作用:将对象、数组转换成字符串 const obj {code: "500",message: "出错了", }; const jsonString JSON.stringify(obj); console.log(jsonString);//"{"code":"Mark Lee","message"…...
【学习笔记】构造函数+重载相关
【学习笔记】构造函数重载相关 一、构造函数 构造函数在创建对象的过程就会执行,带参数与不带参数,带参数的构造函数会默认将成员变量赋值传进去的参数。 class Layer { private:int layer_id; // 层IDstd::string layer_json; // 层的JSON配置…...
JVM——打开JVM后门的钥匙:反射机制
引入 在Java的世界里,反射机制(Reflection)就像一把万能钥匙,能够打开JVM的“后门”,让开发者在运行时突破静态类型的限制,动态操控类的内部结构。想象一下,传统的Java程序如同按菜单点菜的食客…...

第3章——SSM整合
一、整合持久层框架MyBatis 1.准备数据库表及数据 创建数据库:springboot 使用IDEA工具自带的mysql插件来完成表的创建和数据的准备: 创建表 表创建成功后,为表准备数据,如下: 2.创建SpringBoot项目 使用脚手架创建…...

VTK 显示文字、图片及2D/3D图
1. 基本环境设置 首先确保你已经安装了VTK库,并配置好了C开发环境。 #include <vtkSmartPointer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> 2. 显示文字 2D文字 #include &l…...

小白如何在cursor中使用mcp服务——以使用notion的api为例
1. 首先安装node.js,在这一步的时候不要勾选不要勾选 2. 安装完之后,前往notion页面 我的创作者个人资料 | Notion 前往集成页面,添加新集成,自己输入名字,选择内部 新建完之后,进入选择只读 复制密匙 然后前往cursor页面 新建…...

引领AI安全新时代 Accelerate 2025北亚巡展·北京站成功举办
6月5日,网络安全行业年度盛会——"Accelerate 2025北亚巡展北京站"圆满落幕!来自智库、产业界、Fortinet管理层及技术团队的权威专家,与来自各行业的企业客户代表齐聚一堂,围绕"AI智御全球引领安全新时代"主题…...

为什么说数列是特殊的函数
文章目录 前情概要函数特性特殊之处典例剖析前情概要 高三的学生几乎都听老师说过,数列是特殊的函数,那么如何理解这句话呢,无外乎需要关注两点:①函数性,②特殊性,以下举例说明,帮助各位学子理解。 函数特性 既然是按照一定的次序排列而成的一列数字,那么这些数字(…...

解决uniapp开发app map组件最高层级 遮挡自定义解决底部tabbar方法
subNvue,是 vue 页面的原生子窗体,把weex渲染的原生界面当做 vue 页面的子窗体覆盖在页面上。它不是全屏页面,它给App平台vue页面中的层级覆盖和原生界面自定义提供了更强大和灵活的解决方案。它也不是组件,就是一个原生子窗体。 …...

96. 2017年蓝桥杯省赛 - Excel地址(困难)- 进制转换
96. Excel地址(进制转换) 1. 2017年蓝桥杯省赛 - Excel地址(困难) 标签:2017 省赛 1.1 题目描述 Excel 单元格的地址表示很有趣,它使用字母来表示列号。 比如, A 表示第 1 列,…...

PPT转图片拼贴工具 v1.0
软件介绍 这个软件的作用就是将单个PPT的每一页转换为单独的图片,然后将图片进行拼接起来。 但是我没有还没有解决一次性处理多个文件。 效果展示如下: 软件安装 软件源码 import os import re import win32com.client from PIL import Imagedef con…...
大模型在脑梗塞后遗症风险预测及治疗方案制定中的应用研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 国内外研究现状 二、脑梗塞概述 2.1 定义与分类 2.2 发病机制与病理生理过程 2.3 临床表现与诊断方法 三、大模型技术原理与应用现状 3.1 基本概念与技术架构 3.2 在医疗领域的应用案例与优势 3.3 适用于…...
Qwen2.5-VL - 模型结构
Qwen2.5-VL - 模型结构 flyfish 配置项 (Configuration)Qwen2.5-VL-3BQwen2.5-VL-7BQwen2.5-VL-72B视觉Transformer (ViT)隐藏层大小 (Hidden Size)128012801280层数 (# Layers)323232头数 (# Num Heads)161616中间层大小 (Intermediate Size)345634563456patch尺寸 (Patch S…...
【QT常用技术讲解】多线程执行后台命令行的两种方式(后台运行和返回打印信息)
前言 QT调用后台命令行,通常有两种场景:执行命令,等待并获取返回结果;执行命令,让程序后台一直执行(孤儿进程),不需要获取命令返回的结果。以下是分享在国产信创桌面操作系统(麒麟kylin、统信UO…...

【行驶证识别成表格】批量OCR行驶证识别与Excel自动化处理系统,行驶证扫描件和照片图片识别后保存为Excel表格,基于QT和华为ocr识别的实现教程
在车辆管理、物流运输、保险理赔等领域,经常需要处理大量的行驶证信息。传统的人工录入方式效率低、易出错,而使用 OCR 技术可以自动识别行驶证图片中的文字信息,极大提高数据处理效率。该系统可以应用于以下场景: 保险公司快速…...

Linux--进程的状态
1.进程状态在所有系统中宏观的大致模型 1.1、进程状态与变迁 基础状态:涵盖创建、就绪、运行、阻塞、结束等核心状态,描述进程从诞生到消亡的生命周期流转,如创建后进入就绪,争抢 CPU 进入运行,遇 I/O 或资源等待则转…...

(nice!!!)(LeetCode每日一题)2434. 使用机器人打印字典序最小的字符串(贪心+栈)
题目:2434. 使用机器人打印字典序最小的字符串 思路:贪心栈,时间复杂度0(n)。 字符串t其实就是栈,后进先出。要让p的字典序最小,那当然是t每次弹出的字符,都小于或等于“剩下未入t里的字符串的字符”&#…...

008-libb64 你有多理解base64?-C++开源库108杰
正确认识二进制数据和文本数据的关系;深刻理解 base64 编码核心等式:256256256 64646464 经常听到——以至 AI 也会这么回答的:base64 编码用于将二进制数据,转换为文本数据。但是,众所周知,在数字电子计算机中&#…...

电子电路基础2(杂乱)
电容器 容抗 滤波电路(半波) 全波整流 因为A点的电压比D点的电压高,所以D点会走向C点 电感基础 什么是电感器? 一种把电能转换成磁能,并可以将磁能存储起来的元器件。 在嵌入式开发中,电感主要用于动态能量…...

LazyOwn RedTeam/APT 框架是第一个具有人工智能驱动的 CC 的 RedTeam 框架
一、软件介绍 文末提供程序和源码下载 LazyOwn RedTeam/APT 框架是第一个具有人工智能驱动的 C&C 的 RedTeam 框架,具有隐藏活动的 rootkit、与 Windows/Linux/Mac OSX 兼容的不可检测的可塑植入物,以及自配置后门。凭借其 Web 界面和强大的…...

电脑的ip地址会自动变怎么办?原因解析和解决方法
在当今互联网时代,IP地址是每台联网设备的"身份证",但很多用户都遇到过IP地址自动变化的情况。这种现象既可能发生在内网(局域网)环境中,也可能出现在外网(公网)连接中。要理解IP地址…...

PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第一部分)
在填充 PDF 中的图形时(以及许多其他技术中),你可以选择使用 Even-Odd(奇偶) 或 Non-Zero(非零) 填充规则。 对于那些已经在想“你在说啥?”的朋友,别担心,我…...
C++.OpenGL (5/64)变换(Transformation)
变换(Transformation) 变换矩阵核心概念 #mermaid-svg-OvPP9vqkY9MRAHyd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-OvPP9vqkY9MRAHyd .error-icon{fill:#552222;}#mermaid-svg-OvPP9vqkY9MRAHyd .error-tex…...
优化电脑的磁盘和驱动器提高电脑性能和延长硬盘寿命?
磁盘优化 磁盘清理: 使用系统自带的磁盘清理工具(如Windows的“磁盘清理”)删除不必要的文件。清空回收站。删除临时文件和缓存。 磁盘碎片整理(针对机械硬盘): 定期进行磁盘碎片整理,以提高文…...

【八股消消乐】MySQL参数优化大汇总
😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点ÿ…...
JavaSec-SPEL - 表达式注入
简介 SPEL(Spring Expression Language):SPEL是Spring表达式语言,允许在运行时动态查询和操作对象属性、调用方法等,类似于Struts2中的OGNL表达式。当参数未经过滤时,攻击者可以注入恶意的SPEL表达式,从而执行任意代码…...
在 Caliper 中执行不同合约的方法
在 Caliper 中执行不同的智能合约需要通过正确配置工作负载(workload)和测试轮次(rounds),下面我将详细介绍如何执行不同的合约。 1. 通过 config.yaml 配置不同测试轮次 你可以在 config.yaml 中为不同的合约定义不同的测试轮次: rounds:- label: test-helloworlddescript…...