SquareLine风扇显示(2)
218.3.17 SquareLine风扇显示(2)
本节继续在 SquareLine Studio 中制作温湿度风扇控制界面,并在最后导出 UI 文件。视频没有打开或讲解任何 C 源码,也明确说明下一节才把界面与代码结合,因此本节不提前收录配套工程中已经生成的 C 文件。下文用配套工程核对控件参数和事件配置,但不把后续代码当成本节内容补入。
一、思维导图走一遍
上一节已经完成页面背景、顶部标题栏、第一个仪表盘容器 Panel2 和外层圆弧 Arc1。本节继续完成以下内容:
- 在圆弧中央添加一个圆形 Panel,形成仪表盘的内圈;
- 添加温度数值和
temp标签; - 复制整套仪表盘,制作湿度显示区域;
- 添加 LED 控制按钮和事件;
- 添加风扇 PWM 滑块和事件;
- 将完成的界面导出到
21SQL_DHT11/ui目录。
本节重点仍然是熟悉 SquareLine Studio 的控件层级、样式和事件配置,并不实现 DHT11 采集、LED 翻转或 PWM 调速业务逻辑。
完成后的主要层级关系如下:
Screen1Panel1:顶部深色标题栏Label1:系统标题Panel2:左侧温度仪表盘的大容器Arc1:温度仪表盘外圈Panel3:温度仪表盘内圈Label2:温度数值23Label3:温度标识temp
Panel4:右侧湿度仪表盘的大容器Arc2:湿度仪表盘外圈Panel5:湿度仪表盘内圈Label4:湿度数值12Label5:湿度标识humi
Button1:LED 控制按钮Label6:按钮上的LED文字Slider1:风扇 PWM 控制滑块Label7:滑块上的FAN PWM文字
这里的“拖入容器”不是仅让两个控件在画布上重叠,而是要在左侧层级树中形成父子关系。成为子控件后,移动或复制父容器时,里面的控件才会跟随。
二、添加 Panel
2.1 添加 Panel 的操作过程
在第一个仪表盘中央添加新的 Panel,配套工程中它的名称是 Panel3:
- 从控件区添加一个 Panel;
- 在左侧层级树中把它拖到
Panel2下方,使Panel3成为Panel2的子控件; - 将 Width 和 Height 都设为 100 px;
- 设为相对父对象居中,即 Align 选择
CENTER; - 在 Style settings → Background 中将半径设为 80 px;
- 将背景色设为
#646464; - 将 Gradient direction 设为
VER; - 在 Border 中将边框色设为
#000000,边框宽度设为 4 px。
最终参数如下:
| 属性 | 设置值 | 显示作用 |
|---|---|---|
| Width | 100 px | 内圈宽度 |
| Height | 100 px | 内圈高度 |
| Align | CENTER | 位于 Panel2 中央 |
| Background radius | 80 px | 将方形 Panel 的四角充分圆化,显示为圆形 |
| Background color | #646464 | 深灰色内圈 |
| Gradient direction | VER | 沿垂直方向,即从上到下渐变 |
| Border color | #000000 | 黑色边框 |
| Border width | 4 px | 形成明显的内圈轮廓 |
原始笔记把 Arc 识别成了“阿克”,把 Style settings、Background radius 和 Gradient direction 也识别成了多个错误词。尤其要注意:VER 是 vertical 的缩写,表示垂直渐变;视频口头称其为“横向渐变”不准确。若要从左到右进行水平渐变,应选择 HOR。
这里的 80 px 是背景圆角半径,不是这个圆的真实几何半径。对于 100×100 px 的矩形,只要圆角半径足够大,四角就会连接成圆形;继续把数值设得更大,并不会让控件超出原来的 100×100 px 尺寸。
三、添加 Label
3.1 添加数值 Label 的操作过程
接着添加显示温度数值的 Label,配套工程中名称为 Label2:
- 添加 Label 后,在层级树中把它拖入最大的仪表盘容器
Panel2; - 把 Text 改为两位测试数值
23; - 在 Style settings → Text 中将文字颜色设为
#FFFFFF; - 将字体设为
Montserrat 36; - 把数字放在内圈中央略偏上的位置,为下方的温度标识预留空间。
配套工程的最终参数为:
| 属性 | 设置值 |
|---|---|
| Parent | Panel2 |
| Text | 23 |
| Align | CENTER |
| X | 0 px |
| Y | -12 px |
| Text color | #FFFFFF |
| Font | Montserrat 36 |
原始笔记中的 “money street” 是 Montserrat 的语音识别错误。Montserrat 是字体名称,后面的 36 表示此处选择的字号。
Label2 在层级上是 Panel2 的直接子控件,并不是 Panel3 的子控件。它只是视觉上覆盖在圆形 Panel3 的上方。这样既能让它随整个 Panel2 移动,又不需要使用 Panel3 的局部坐标重新定位。
四、继续添加 Label 和 Panel
4.1 添加温度说明 Label
再添加一个 Label,作为温度含义的提示文字。配套工程中的名称是 Label3:
| 属性 | 设置值 |
|---|---|
| Parent | Panel2 |
| Text | temp |
| Align | CENTER |
| X | -1 px |
| Y | 18 px |
| Text color | #FFFFFF |
| Font | Montserrat 16 |
temp 是 temperature 的常见缩写,表示温度。它位于数值 23 下方,因此数值要稍微上移,两行文字才不会重叠。
视频中一度尝试过 18 号字体,随后又选择了 16 号字体;配套工程导出的最终结果是 Montserrat 16。精校时应以本节最终保存和导出的项目状态为准。
4.2 第一个仪表盘的组成
第一个仪表盘并不是一张整体图片,而是由四个控件叠加而成:
| 控件 | 作用 |
|---|---|
Panel2 | 管理整套仪表盘的父容器 |
Arc1 | 绘制外层圆弧和轨道 |
Panel3 | 形成深灰渐变的圆形内圈 |
Label2、Label3 | 显示数值与 temp 标识 |
这种组合方式的优点是:后续程序可以单独更新圆弧值和数字文字,而不需要重新绘制整张背景图片;复制 Panel2 时,其所有子控件也能一起复制。
五、更改第一个大容器的边框颜色
Panel2 默认边框与页面背景存在色差,会看到一个不需要的矩形轮廓。课堂没有把边框宽度设为 0,而是把 Panel2 的边框色改成与屏幕背景相同的:
#4B4B55
Panel2 的背景本来也是 #4B4B55,因此它会在视觉上融入页面,只留下内部的圆形仪表盘。
“看不见边框”不等于“删除了容器”。Panel2 仍然存在,并继续承担以下作用:
- 保存
Arc1、Panel3、Label2和Label3的父子关系; - 统一控制这组控件的位置;
- 作为下一步复制整个仪表盘的对象。
如果只在画布上单击时难以选中透明或同色容器,可以直接在左侧层级树中选择 Panel2,再修改右侧属性。
六、复制第二个大容器并更改数字和文字
第二个仪表盘不需要从头搭建。选中 Panel2,点击层级树对应项目后的三个点,选择复制操作。复制得到的容器及其子控件在配套工程中分别命名为:
Panel4:第二个大容器;Arc2:第二个外层圆弧;Panel5:第二个圆形内圈;Label4:第二个数值;Label5:第二个说明文字。
复制完成时,新旧控件完全重叠,所以画面看起来可能没有变化。拖动新容器后,才能看到两套仪表盘已经存在。
课堂将第二个仪表盘中的数值改为 12,把文字从 temp 改为 humi。humi 是 humidity(湿度)的缩写。这里的 23 和 12 都只是界面设计阶段的占位值,下一节才会尝试用真实温湿度数据更新它们。
最终两组仪表盘参数如下:
| 对象 | X | Y | 数值文字 | 说明文字 |
|---|---|---|---|---|
Panel2(温度) | -108 px | 0 px | 23 | temp |
Panel4(湿度) | 101 px | 0 px | 12 | humi |
视频中间曾出现 Y=3 和 Y=7,老师先把两者对齐,再把容器略微上移,为底部按钮与滑块留出空间。最终导出工程中两者的 Y 坐标均为 0,所以不要把中途调试值误记成最终参数。
七、添加控制按键
7.1 添加控制按键的操作过程
从控件区添加 Button,作为 LED 控制按钮。配套工程中的对象名为 Button1,最终参数如下:
| 属性 | 设置值 |
|---|---|
| Parent | Screen1 |
| Width | 100 px |
| Height | 50 px |
| Align | CENTER |
| X | -111 px |
| Y | 115 px |
| Background color | #646464 |
| Gradient direction | VER |
该按钮位于界面左下方。和前面的圆形 Panel 一样,VER 仍表示垂直渐变。视频没有指定第二个渐变色等更细参数,主要目的是练习通过 Style settings 修改按钮背景效果。
Button 只是可交互控件。此时它还不会控制开发板上的 LED,必须继续添加事件,并在导出后为回调函数填写实际业务代码。
八、添加事件
8.1 给 LED 按钮添加事件
选中 Button1,在右侧 Inspector 面板底部配置事件:
- 找到 Events 区域并点击 Add Event;
- 事件触发类型选择
CLICKED; - Action 选择
Call function; - 点击 Action 中的 Add;
- 函数名填写
LED_Switch。
原始转录中的“爱的英文头”“靠方格神”和“毁掉函数”分别是 Add Event、Call function 和“回调函数”的识别错误。
这里要理解三个层次:
CLICKED:规定何时触发,本项目是在按钮点击并释放后触发;Call function:规定触发后执行一个函数;LED_Switch:规定生成并调用的函数名称。
SquareLine 导出后会为 LED_Switch 生成函数声明和空的函数骨架,但不会自动知道 LED 接在哪个 GPIO,也不会自动生成灯控逻辑。因此,完成这一操作只能说明“界面事件入口已经建立”,不能说明 LED 已经能够点亮。真正的 GPIO 控制在后续课程中实现。
函数名必须保持大小写和下划线一致。LED_Switch、led_switch 和 LED_switch 在 C 语言中是三个不同的标识符;本课最终工程使用的是 LED_Switch。
九、添加 Label
9.1 添加 LED 指示文字
添加 Label 并把文字设为 LED,用于说明左下方按钮的功能。配套工程中该对象名为 Label6:
| 属性 | 设置值 |
|---|---|
| Parent | Screen1 |
| Text | LED |
| Align | CENTER |
| X | -113 px |
| Y | 113 px |
| Text color | #FFFFFF |
| Font | Montserrat 20 |
从视觉上看,Label6 位于 Button1 中央;但配套工程表明它和按钮都是 Screen1 的直接子控件,并不是按钮的子控件。因此移动按钮时,Label 不会自动跟随,必须一起调整位置。
如果在自己的工程中把 Label 直接设成 Button 的子控件,也能实现按钮文字随父对象移动,但这会改变课程工程的层级与坐标。精校笔记只记录视频及配套工程的实际做法,不擅自改写结构。
十、添加 Slider
10.1 添加 Slider 的操作过程
在界面右下方添加 Slider,作为风扇 PWM 调节入口。配套工程中的名称为 Slider1:
| 属性 | 设置值 |
|---|---|
| Parent | Screen1 |
| Width | 153 px |
| Height | 33 px |
| Align | CENTER |
| X | 102 px |
| Y | 113 px |
| 初始值 | 0 |
Slider 由背景轨道、已填充指示区域和可拖动旋钮组成。拖动旋钮会改变 Slider 的数值;界面程序之后可以读取该数值,再换算为定时器 PWM 的比较值或占空比。
视频主要通过鼠标拖拽调整 Slider 的尺寸,并要求左右布局看起来协调。配套工程最终导出的精确尺寸为 153×33 px,位置为 X=102、Y=113。
10.2 添加 Slider 事件
课堂给 Slider 添加事件的步骤与按钮基本相同:
- 选中
Slider1; - 在 Events 中点击 Add Event;
- 事件类型选择
CLICKED; - Action 选择
Call function; - 添加函数名
Fan_PWM_Control。
配套工程确认,本课实际保存并导出的事件类型确实是 CLICKED,回调函数名为 Fan_PWM_Control。该函数此时也只是空骨架,尚未包含读取 Slider 值和修改 PWM 的业务逻辑。
需要额外区分两个 LVGL 事件:
| 事件 | 触发时机 | 适用场景 |
|---|---|---|
CLICKED | 对象被按下后释放,且没有被判定为滚动时触发 | 按钮点击、松手后执行一次操作 |
VALUE_CHANGED | Slider 的值在拖动过程中发生变化时持续触发 | 实时更新百分比、实时调节 PWM |
本课必须按视频保留 CLICKED,不能擅自改写工程;但从 LVGL 8.3 的事件语义看,如果后续目标是让风扇转速在拖动过程中连续跟随 Slider 变化,通常应使用 VALUE_CHANGED。是否修改要结合下一节实际业务代码判断。
10.3 添加 FAN PWM 说明文字
最后添加 Label7,覆盖在 Slider 的视觉中央:
| 属性 | 设置值 |
|---|---|
| Parent | Screen1 |
| Text | FAN PWM |
| Align | CENTER |
| X | 102 px |
| Y | 114 px |
| Text color | #FEFEFE |
| Font | Montserrat 20 |
视频转录把这里识别成了 “pwm control”,但最终 SquareLine 工程和导出的 UI 文件均为 FAN PWM。#FEFEFE 是非常接近纯白的颜色;严格的纯白是 #FFFFFF,两者肉眼差异很小,但精校时仍应保留工程中的实际值。
10.4 保存与导出 UI
界面完成后执行以下操作:
- 先按
Ctrl+S保存 SquareLine 工程; - 点击 Export 导出 UI 文件;
- 进入课程的
21SQL_DHT11工程目录; - 新建并选择
ui文件夹作为导出位置; - 导出结束后再次确认工程已经保存。
配套工程中实际生成了 ui.c、ui.h、ui_events.c、ui_events.h、ui_helpers.c、ui_helpers.h、screens/ui_Screen1.c 等文件。其中:
ui_Screen1.c保存本课设计的控件创建和样式参数;ui.c负责界面对象变量、事件转接和ui_init();ui_events.c保存LED_Switch与Fan_PWM_Control的空函数骨架;ui_helpers.c是 SquareLine 生成的通用辅助代码。
导出 UI 只把设计结果转换成 LVGL 可用的文件,并不等于已经完成 STM32 移植。要在开发板上运行,还需要正确初始化 LVGL、显示驱动、触摸输入和周期性任务,并把导出文件加入 Keil 工程;这些属于下一节及后续课程内容。
10.5 本课核对清单
Panel3是Panel2的子控件,尺寸为 100×100 px;Panel3的背景色为#646464,VER表示垂直渐变,黑色边框宽 4 px;- 数值 Label 使用 Montserrat 36,说明 Label 使用 Montserrat 16;
Panel2的边框色改为屏幕背景色#4B4B55,只是视觉隐藏,并未删除容器;- 复制
Panel2可连同所有子控件一起得到第二套仪表盘; - 最终温度占位值为
23/temp,湿度占位值为12/humi; - LED 按钮事件为
CLICKED → Call function → LED_Switch; - Slider 事件为
CLICKED → Call function → Fan_PWM_Control; - Slider 说明文字最终是
FAN PWM,不是转录中的 “pwm control”; - 本课只生成回调函数空骨架,没有实现 LED 和 PWM 控制代码;
- UI 导出到
21SQL_DHT11/ui,下一节才把界面与单片机业务代码结合。