SquareLine风扇显示(2)

Tutorial: 卓越工程师 Category: 嵌入式 Published: 2026-10-23 11:05:29 Views: 0 Likes: 0 Comments: 0

218.3.17 SquareLine风扇显示(2)

本节继续在 SquareLine Studio 中制作温湿度风扇控制界面,并在最后导出 UI 文件。视频没有打开或讲解任何 C 源码,也明确说明下一节才把界面与代码结合,因此本节不提前收录配套工程中已经生成的 C 文件。下文用配套工程核对控件参数和事件配置,但不把后续代码当成本节内容补入。

一、思维导图走一遍

上一节已经完成页面背景、顶部标题栏、第一个仪表盘容器 Panel2 和外层圆弧 Arc1。本节继续完成以下内容:

  1. 在圆弧中央添加一个圆形 Panel,形成仪表盘的内圈;
  2. 添加温度数值和 temp 标签;
  3. 复制整套仪表盘,制作湿度显示区域;
  4. 添加 LED 控制按钮和事件;
  5. 添加风扇 PWM 滑块和事件;
  6. 将完成的界面导出到 21SQL_DHT11/ui 目录。

本节重点仍然是熟悉 SquareLine Studio 的控件层级、样式和事件配置,并不实现 DHT11 采集、LED 翻转或 PWM 调速业务逻辑。

完成后的主要层级关系如下:

  • Screen1
    • Panel1:顶部深色标题栏
    • Label1:系统标题
    • Panel2:左侧温度仪表盘的大容器
      • Arc1:温度仪表盘外圈
      • Panel3:温度仪表盘内圈
      • Label2:温度数值 23
      • Label3:温度标识 temp
    • Panel4:右侧湿度仪表盘的大容器
      • Arc2:湿度仪表盘外圈
      • Panel5:湿度仪表盘内圈
      • Label4:湿度数值 12
      • Label5:湿度标识 humi
    • Button1:LED 控制按钮
    • Label6:按钮上的 LED 文字
    • Slider1:风扇 PWM 控制滑块
    • Label7:滑块上的 FAN PWM 文字

这里的“拖入容器”不是仅让两个控件在画布上重叠,而是要在左侧层级树中形成父子关系。成为子控件后,移动或复制父容器时,里面的控件才会跟随。

二、添加 Panel

2.1 添加 Panel 的操作过程

在第一个仪表盘中央添加新的 Panel,配套工程中它的名称是 Panel3:

  1. 从控件区添加一个 Panel;
  2. 在左侧层级树中把它拖到 Panel2 下方,使 Panel3 成为 Panel2 的子控件;
  3. 将 Width 和 Height 都设为 100 px;
  4. 设为相对父对象居中,即 Align 选择 CENTER;
  5. 在 Style settings → Background 中将半径设为 80 px;
  6. 将背景色设为 #646464;
  7. 将 Gradient direction 设为 VER;
  8. 在 Border 中将边框色设为 #000000,边框宽度设为 4 px。

最终参数如下:

属性设置值显示作用
Width100 px内圈宽度
Height100 px内圈高度
AlignCENTER位于 Panel2 中央
Background radius80 px将方形 Panel 的四角充分圆化,显示为圆形
Background color#646464深灰色内圈
Gradient directionVER沿垂直方向,即从上到下渐变
Border color#000000黑色边框
Border width4 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:

  1. 添加 Label 后,在层级树中把它拖入最大的仪表盘容器 Panel2;
  2. 把 Text 改为两位测试数值 23;
  3. 在 Style settings → Text 中将文字颜色设为 #FFFFFF;
  4. 将字体设为 Montserrat 36;
  5. 把数字放在内圈中央略偏上的位置,为下方的温度标识预留空间。

配套工程的最终参数为:

属性设置值
ParentPanel2
Text23
AlignCENTER
X0 px
Y-12 px
Text color#FFFFFF
FontMontserrat 36

原始笔记中的 “money street” 是 Montserrat 的语音识别错误。Montserrat 是字体名称,后面的 36 表示此处选择的字号。

Label2 在层级上是 Panel2 的直接子控件,并不是 Panel3 的子控件。它只是视觉上覆盖在圆形 Panel3 的上方。这样既能让它随整个 Panel2 移动,又不需要使用 Panel3 的局部坐标重新定位。

四、继续添加 Label 和 Panel

4.1 添加温度说明 Label

再添加一个 Label,作为温度含义的提示文字。配套工程中的名称是 Label3:

属性设置值
ParentPanel2
Texttemp
AlignCENTER
X-1 px
Y18 px
Text color#FFFFFF
FontMontserrat 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 都只是界面设计阶段的占位值,下一节才会尝试用真实温湿度数据更新它们。

最终两组仪表盘参数如下:

对象XY数值文字说明文字
Panel2(温度)-108 px0 px23temp
Panel4(湿度)101 px0 px12humi

视频中间曾出现 Y=3 和 Y=7,老师先把两者对齐,再把容器略微上移,为底部按钮与滑块留出空间。最终导出工程中两者的 Y 坐标均为 0,所以不要把中途调试值误记成最终参数。

七、添加控制按键

7.1 添加控制按键的操作过程

从控件区添加 Button,作为 LED 控制按钮。配套工程中的对象名为 Button1,最终参数如下:

属性设置值
ParentScreen1
Width100 px
Height50 px
AlignCENTER
X-111 px
Y115 px
Background color#646464
Gradient directionVER

该按钮位于界面左下方。和前面的圆形 Panel 一样,VER 仍表示垂直渐变。视频没有指定第二个渐变色等更细参数,主要目的是练习通过 Style settings 修改按钮背景效果。

Button 只是可交互控件。此时它还不会控制开发板上的 LED,必须继续添加事件,并在导出后为回调函数填写实际业务代码。

八、添加事件

8.1 给 LED 按钮添加事件

选中 Button1,在右侧 Inspector 面板底部配置事件:

  1. 找到 Events 区域并点击 Add Event;
  2. 事件触发类型选择 CLICKED;
  3. Action 选择 Call function;
  4. 点击 Action 中的 Add;
  5. 函数名填写 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:

属性设置值
ParentScreen1
TextLED
AlignCENTER
X-113 px
Y113 px
Text color#FFFFFF
FontMontserrat 20

从视觉上看,Label6 位于 Button1 中央;但配套工程表明它和按钮都是 Screen1 的直接子控件,并不是按钮的子控件。因此移动按钮时,Label 不会自动跟随,必须一起调整位置。

如果在自己的工程中把 Label 直接设成 Button 的子控件,也能实现按钮文字随父对象移动,但这会改变课程工程的层级与坐标。精校笔记只记录视频及配套工程的实际做法,不擅自改写结构。

十、添加 Slider

10.1 添加 Slider 的操作过程

在界面右下方添加 Slider,作为风扇 PWM 调节入口。配套工程中的名称为 Slider1:

属性设置值
ParentScreen1
Width153 px
Height33 px
AlignCENTER
X102 px
Y113 px
初始值0

Slider 由背景轨道、已填充指示区域和可拖动旋钮组成。拖动旋钮会改变 Slider 的数值;界面程序之后可以读取该数值,再换算为定时器 PWM 的比较值或占空比。

视频主要通过鼠标拖拽调整 Slider 的尺寸,并要求左右布局看起来协调。配套工程最终导出的精确尺寸为 153×33 px,位置为 X=102、Y=113。

10.2 添加 Slider 事件

课堂给 Slider 添加事件的步骤与按钮基本相同:

  1. 选中 Slider1;
  2. 在 Events 中点击 Add Event;
  3. 事件类型选择 CLICKED;
  4. Action 选择 Call function;
  5. 添加函数名 Fan_PWM_Control。

配套工程确认,本课实际保存并导出的事件类型确实是 CLICKED,回调函数名为 Fan_PWM_Control。该函数此时也只是空骨架,尚未包含读取 Slider 值和修改 PWM 的业务逻辑。

需要额外区分两个 LVGL 事件:

事件触发时机适用场景
CLICKED对象被按下后释放,且没有被判定为滚动时触发按钮点击、松手后执行一次操作
VALUE_CHANGEDSlider 的值在拖动过程中发生变化时持续触发实时更新百分比、实时调节 PWM

本课必须按视频保留 CLICKED,不能擅自改写工程;但从 LVGL 8.3 的事件语义看,如果后续目标是让风扇转速在拖动过程中连续跟随 Slider 变化,通常应使用 VALUE_CHANGED。是否修改要结合下一节实际业务代码判断。

10.3 添加 FAN PWM 说明文字

最后添加 Label7,覆盖在 Slider 的视觉中央:

属性设置值
ParentScreen1
TextFAN PWM
AlignCENTER
X102 px
Y114 px
Text color#FEFEFE
FontMontserrat 20

视频转录把这里识别成了 “pwm control”,但最终 SquareLine 工程和导出的 UI 文件均为 FAN PWM。#FEFEFE 是非常接近纯白的颜色;严格的纯白是 #FFFFFF,两者肉眼差异很小,但精校时仍应保留工程中的实际值。

10.4 保存与导出 UI

界面完成后执行以下操作:

  1. 先按 Ctrl+S 保存 SquareLine 工程;
  2. 点击 Export 导出 UI 文件;
  3. 进入课程的 21SQL_DHT11 工程目录;
  4. 新建并选择 ui 文件夹作为导出位置;
  5. 导出结束后再次确认工程已经保存。

配套工程中实际生成了 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,下一节才把界面与单片机业务代码结合。

10.6 参考资料