【电子量产工具】4. UI系统

news2024/9/24 9:23:38

文章目录

  • 前言
  • 一、UI界面分析
  • 二、结构体描述按钮
  • 三、按钮初始化
  • 四、默认绘制按键事件函数
  • 五、默认按下按键事件函数
  • 六、测试程序
  • 实验效果
  • 总结

前言

最近看了 电子量产工具 这个项目,本专栏是对该项目的一个总结。


一、UI界面分析

在这里插入图片描述

UI用户界面(User Interface)的缩写,指的是人与计算机或其他设备进行交互时所使用的界面。用户界面是用户与系统之间的桥梁,提供了一种方式让用户与计算机进行沟通、操作和获取信息。
用户界面可以包括以下几个方面:

  • 图形用户界面(GUI)。
  • 命令行界面(CLI)
  • 触摸界面
  • 声音界面
  • 虚拟现实界面(VR)和增强现实界面(AR)

我们的UI系统,就是构造各类GUI元素,比如按钮(目前只实现按钮)。

二、结构体描述按钮

/* 函数指针(绘制按键) */
typedef int (*ONDRAW_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff);
/* 函数指针(按下按钮) */
typedef int (*ONPRESSED_FUNC)(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent);


typedef struct Button {
	char *name;								// 按键 名字
	int status;								//按键 按下状态
	Region tRegion;							// 按键的区域
	ONDRAW_FUNC OnDraw;						//一个 ONDRAW_FUNC 类型的函数指针,用于指向按钮绘制函数
	ONPRESSED_FUNC OnPressed;				//一个 ONPRESSED_FUNC 类型的函数指针,用于指向按钮按下事件处理函数
}Button, *PButton;
typedef struct Region {				//区域包括 左上角坐标, 高, 宽
	int iLeftUpX;
	int iLeftUpY;
	int iWidth;
	int iHeigh;
}Region, *PRegion;

三、按钮初始化

void InitButton(PButton ptButton, char *name, PRegion ptRegion, ONDRAW_FUNC OnDraw, ONPRESSED_FUNC OnPressed)
{
	ptButton->status = 0;				//初始状态为 0 ,未按下
	ptButton->name = name;
	ptButton->tRegion = *ptRegion;			// 按钮的区域
	ptButton->OnDraw    = OnDraw ? OnDraw : DefaultOnDraw;		//若 OnDraw 为空,则执行默认绘制函数DefaultOnDraw
	ptButton->OnPressed = OnPressed ? OnPressed : DefaultOnPressed;	 //若 OnPressed 为空,则执行默认绘制函数DefaultOnPressed
}

四、默认绘制按键事件函数

绘制各个按钮 Button 的底色,文字,并将其刷新到 DispBuff 上

static int DefaultOnDraw(struct Button *ptButton, PDispBuff ptDispBuff)
{
	/* 绘制底色 */
	DrawRegion(&ptButton->tRegion, BUTTON_DEFAULT_COLOR);		// 红色 0xff0000

	/* 居中写文字 */
	DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);		//黑色 0x000000

	/* flush to lcd/web */
	FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);

	return 0;
}
  1. 绘制底色
void DrawRegion(PRegion ptRegion, unsigned int dwColor)
{
	int x = ptRegion->iLeftUpX;
	int y = ptRegion->iLeftUpY;
	int width = ptRegion->iWidth;
	int heigh = ptRegion->iHeigh;

	int i,j;

	for (j = y; j < y + heigh; j++)
	{
		for (i = x; i < x + width; i++)
			PutPixel(i, j, dwColor);			//描点函数
	}
}
  1. 居中写文字
    在 一定的区域 Region,按颜色 dwColor 居中显示名字 name
void DrawTextInRegionCentral(char *name, PRegion ptRegion, unsigned int dwColor)
{
	int n = strlen(name);
	int iFontSize = ptRegion->iWidth / n / 2;
	FontBitMap tFontBitMap;

	int iOriginX, iOriginY;
	int i = 0;
	int error;

	if (iFontSize > ptRegion->iHeigh)				//计算字体大小
		iFontSize =  ptRegion->iHeigh;
		
	/* 当前文字的基点 */
	iOriginX = (ptRegion->iWidth - n * iFontSize)/2 + ptRegion->iLeftUpX;
	iOriginY = (ptRegion->iHeigh - iFontSize)/2 + iFontSize + ptRegion->iLeftUpY;

	SetFontSize(iFontSize);					// 设置字体大小

	while (name[i])			//字符编码
	{
		/* get bitmap */
		tFontBitMap.iCurOriginX = iOriginX;
		tFontBitMap.iCurOriginY = iOriginY;
		error = GetFontBitMap(name[i], &tFontBitMap);		//根据字符编码获取位图,保存在 参数 tFontBitMap中
		if (error)
		{
			printf("SelectAndInitFont err\n");
			return;
		}

		/* draw on buffer */		
		DrawFontBitMap(&tFontBitMap, dwColor);			// 绘制位图	

		iOriginX = tFontBitMap.iNextOriginX;			//获取下一文字的基点坐标
		iOriginY = tFontBitMap.iNextOriginY;	
		i++;
	}
}
  1. 将绘制到的按钮,刷新到 buffer 上。

返回 LCDframebuffer , 以后上层 APP 可以直接操作LCD, 可以不用 FbFlushRegion
也可以 malloc 返回一块无关的buffer, 要使用 FbFlushRegion

这里 为了 以后代码的可移植性,加上了刷新界面,但 并未做出任何举动。

在这里插入图片描述

五、默认按下按键事件函数

按下按键事件函数 也需要 上面 绘制函数 里的 : 绘制底色, 居中写文字 ,刷新界面。这里就不再 重述了。

static int DefaultOnPressed(struct Button *ptButton, PDispBuff ptDispBuff, PInputEvent ptInputEvent)
{
	unsigned int dwColor = BUTTON_DEFAULT_COLOR;		//按钮初始颜色 红色,0xff0000
	
	ptButton->status = !ptButton->status;				// 按钮状态,未按下时 为 0 
	if (ptButton->status)
		dwColor = BUTTON_PRESSED_COLOR;					//按下的颜色为 绿色, 0x00ff00

	/* 绘制底色 */
	DrawRegion(&ptButton->tRegion, dwColor);

	/* 居中写文字 */
	DrawTextInRegionCentral(ptButton->name, &ptButton->tRegion, BUTTON_TEXT_COLOR);

	/* 刷新界面 到 lcd/web */
	FlushDisplayRegion(&ptButton->tRegion, ptDispBuff);
	return 0;
}

六、测试程序

  1. 显示界面初始化
    在这里插入图片描述
  2. 字体初始化
    在这里插入图片描述
  3. ui 界面
	/* 设置按钮的显示位置,宽高 */
	tRegion.iLeftUpX = 200;
	tRegion.iLeftUpY = 200;
	tRegion.iWidth   = 300;
	tRegion.iHeigh   = 100;
	
	/* 显示 "test", 调用默认绘制,按下函数 */
	InitButton(&tButton, "test", &tRegion, NULL, NULL);
	tButton.OnDraw(&tButton, ptBuffer);				//绘制按键
	while (1)
	{
		tButton.OnPressed(&tButton, ptBuffer, NULL);	//按下按键,
		sleep(2);		// 休眠 2 秒
	}

实验效果

实验结果就是每隔 2 秒,自动 变换按键的颜色。(我按钮后面的图是 自己的QT界面,忽略即可)
在这里插入图片描述
在这里插入图片描述


总结

UI 系统界面的逻辑性 不难,就是一些函数的编写有些困难。
这些封装好的代码,可以用于以后代码的一直调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/732121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GEE:提取地区 NDVI/LST/RVI 并进行时间序列线性插值和SG滤波

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用Landsat数据集&#xff0c;构建时间序列&#xff0c;并使用线性插值算法填补缺失数据&#xff0c;或者去云空洞&#xff0c;并进一步对完整的时间序列数据进行SG滤波处理。 文章目录 一、代码二、代码链接三、需要请私聊 一、代…

OPCUA 的历史数据库/聚合服务器的实现细节

进入了AI 大数据时代&#xff0c;无论是工业自动化系统&#xff0c;还是物联网系统&#xff0c;对大数据的采集&#xff0c;存储和分析都十分重要。大数据被称为工业的石油&#xff0c;未来制造业的持续改善离不开大数据。 传统的应用中&#xff0c;历史数据的存储是特定的数据…

官方外设库SDA安装和验证

第一种方法 1.打开mobaxterm&#xff0c;通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP下载压缩包&#xff0c;点击上传外设库的压缩包 2.输入命令 unzip 解压 3.输入命令 sudo ./build 安装工具包 4.验证安装完毕用 输入gpio readall 显示下面图片 第二…

数据分析实战(基础篇):从数据探索到模型解释

前言 本文着重介绍数据分析实战的基础知识和技巧&#xff0c;探索从数据探索到建模再到模型解释的完整过程内容包含数据探索、模型建立、调参技巧、SHAP模型解释数据来源于kaggle平台&#xff0c;crab age prediction数据集&#xff0c;数据详情 数据说明 数据背景 螃蟹味道…

【性能设计篇】聊聊异步处理

在性能设计的时候&#xff0c;其实主要的三板斧就是数据库(读写分离、分库分表)&#xff0c;缓存&#xff08;提升读性能&#xff09;&#xff0c;异步处理&#xff08;提升写性能&#xff09;以及相关的秒杀设计以及边缘设计等。 本篇主要介绍异步处理的哪些事&#xff0c;我们…

6.2.1 网络基本服务---域名解析系统DNS

6.2.1 网络基本服务—域名解析系统DNS 因特网是需要提供一些最基本的服务的&#xff0c;今天我们就来讨论一下这些基本的服务。 域名系统&#xff08;DNS&#xff09;远程登录&#xff08;Telnet&#xff09;文件传输协议&#xff08;FTP&#xff09;动态主机配置协议&#x…

Day47

思维导图 练习 实现登录框中&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;并跳转到其他界面 second.h #ifndef SECOND_H #define SECOND_H#include <QWidget>namespace Ui { class Second; }class Second : public QWidget {Q_OBJECTpublic:explicit …

Matlab绘图时的几个小技巧(修改刻度线长度、添加/去掉右边和上面的轴与刻度线、出图时去掉旁边的空白部分)

set(gca,TickLength,[0.005,0.035]); %修改坐标轴刻度线的长度 box on; %开启右面和上面的坐标轴 box off;%关闭右面和上面的坐标轴 set(gca, LooseInset, [0,0,0,0]);%删除掉图旁边多余的空白部分首先随便出一张图 我想让刻度线更长或更短一些&#xff1a; 我想让右侧和上面…

OpenCV的安装与配置指南(Windows环境,Python语言)

OpenCV 的安装与配置指南&#xff08;Windows环境&#xff0c;Python语言&#xff09; 导语一、安装 Python 二、安装 OpenCV 库三、配置 OpenCV 环境变量四、验证 OpenCV 安装总结 导语 OpenCV 是一个功能强大的计算机视觉库&#xff0c;广泛应用于图像处理和计算机视觉领域。…

第十二章 elk

1、ELK可以帮助我们解决哪些问题 日志分布在多台不同的服务器上,业务一旦出现故障,需要一台台查看日志 单个日志文件巨大,无法使用常用的文本工具分析,检索困难; 2、架构设计分析 Filebeat和Logstash ELK架构中使用Logstash收集、解析日志,但是Logstash对内存、cpu、i…

MySQL入门必备:Linux中部署MySQL环境的四种方式详解

目录 一、仓库安装 二、本地安装 三、Docker中安装 四、源码安装 一、仓库安装 首先需要下载mysql软件包&#xff1a; 1、进入MySQL官网 2、进入MySQL社区版下载 3、使用yum方式下载MySQL 4、下载对应版本的软件包 5、这里可以不登录直接下载软件包 6、复制下载链接 7、然…

Perfetto详细解析

一、Perfetto基础 1、Perfetto介绍 Perfetto 是一个生产级的开源堆栈&#xff0c;用于提高性能 仪器和痕量分析。与 Systrace 不同&#xff0c;它提供数据源超集&#xff0c;可以用 protobuf 编码的二进制流形式记录任意长度的跟踪记录。可以将Perfetto理解为systrace的升级版…

Python——爬虫入门

爬虫的流程 第一步:获取网页内容 浏览器访问网页时也是一样&#xff0c;都是先发个请求获取网页内容&#xff0c;但是浏览器多了个渲染的步骤。 程序获取的内容都是网页源代码 第二步:解析网页内容 第三步:储存或分析数据 要做数据集就存起来&#xff0c;要做数据分析就形…

【Matlab】GRNN神经网络遗传算法(GRNN-GA)函数极值寻优——非线性函数求极值

上一篇博客介绍了BP神经网络遗传算法(BP-GA)函数极值寻优——非线性函数求极值&#xff0c;神经网络用的是BP神经网络&#xff0c;本篇博客将BP神经网络替换成GRNN神经网络&#xff0c;希望能帮助大家快速入门GRNN网络。 1.背景条件 要求&#xff1a;对于未知模型&#xff08;…

scratch 角色追踪

scratch 角色追踪 本程序中一个角色移动到随机位置和方向后向前移动&#xff0c;碰到边缘反弹&#xff1b;另一个角色跟随前一个角色&#xff0c;两个角色接触后前者重新取随机位置。 程序内容如下

Linux——进程信号详解

目录 一.进程信号的理解 1.1定义&#xff1a; 1.2举例&#xff1a; 1.3总结&#xff1a; 二.进程信号地使用&#xff1a; 2.1信号种类&#xff1a; 2.2而操作系统向进程发送信号地方式有四种&#xff1a; 2.2.1以键盘的方式向进程发送信号 接下来介绍一个系统调用函数sign…

【项目】C++实现高并发内存池

文章目录 一、项目介绍1.1 项目原型1.2 池化技术1.3 内存池主要解决的问题1.4 malloc理解 二、定长内存池实现三、高并发内存池的三层申请内存框架设计3.1 thread cache层的设计3.1.1 thread cache整体框架3.1.2 哈希桶映射对齐规则3.1.3 thread cacheTLS无锁访问 3.2 central …

【剑指offer】10. 矩阵中的路径(java)

文章目录 矩阵中的路径描述示例1示例2思路完整代码 矩阵中的路径 描述 请设计一个函数&#xff0c;用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始&#xff0c;每一步可以在矩阵中向左&#xff0c;向右&…

springboot切面应用

1、切面场景 无侵入的实现功能增强 2、实现 切面类的实现 需要使用注解Aspect和Componet来实现&#xff0c; 环绕通知的作用在返回的student的sname后面拼接around字符串。 后置通知的作用在入参后面拼接idididdi&#xff0c;然后打印日志 Aspect Component public class…

English Learning - L3 纠音 W9 Lesson7-8 Ted Living Beyond Limits 2023.7.4 周二

朗读内容&#xff1a; Lesson 7-8 Day 52 - 60 句子 Ted Living Beyond Limits 23-50