菜单

STTStyle使用手册

下载

STTStyle.h 使用手册

STTStyle.h 提供三类能力:

  1. 与 LVGL 结构体布局对应的公开类型。
  2. 按属性分组的样式读写包装器。
  3. 动画、滚动和 Flex/Grid 布局辅助方法。

这些 API 基本直接调用 LVGL,不做范围、空指针或线程检查。

1. 最重要的安全规则

通过控件取得样式:

cpp 复制代码
widget->getStyle()->p_bg
    ->setColor(0xffffff)
    ->setOpa(255);

不要长期缓存返回的 STTStyle*:

cpp 复制代码
// 不安全
STTStyle* aStyle = widgetA->getStyle();
widgetB->getStyle();
aStyle->p_bg->setColor(0xff0000); // 实际可能改到 widgetB

当前 STTStyleHelper::attach 全进程只复用一个 global_stt_style_helper。每次 attach/getStyle 都会把同一包装器及其子属性对象重新指向最新 object。因此:

  • 推荐每条样式链从目标 widget->getStyle() 开始并立即完成。
  • 不跨语句、函数、线程缓存 STTStyle* 或其 p_bg/p_text 等子指针。
  • 样式 API 只能在 LVGL UI 线程串行使用。

安全写法:

cpp 复制代码
widgetA->getStyle()->p_bg->setColor(0xff0000);
widgetB->getStyle()->p_bg->setColor(0x00ff00);

2. selector

selector 是“部件 | 状态”:

部件常用值:

值 部件
0x000000 Main
0x010000 Scrollbar
0x020000 Indicator
0x030000 Knob
0x040000 Selected
0x050000 Items
0x060000 Ticks
0x070000 Cursor
0x080000 Custom first
0x0F0000 Any part

状态常用值:

值 状态
0x0000 Default
0x0001 Checked
0x0002 Focused
0x0004 Focus key
0x0008 Edited
0x0010 Hovered
0x0020 Pressed
0x0040 Scrolled
0x0080 Disabled
cpp 复制代码
int selector = stt::constant::Part::Indic |
               stt::constant::WidgetState::CHECKED;
widget->getStyle()->p_bg->setColor(0x18a765, selector);

STTStyle 构造/attach 的 selector 成员当前没有自动合并到每个方法的默认 selector。需要非 Main/Default 时,始终给具体 set/get 方法显式传 selector。

3. LVGL 映射类型

类型 用途
LvCoord 坐标,当前 USE_LARGE_COORD=1 时为 int32_t
LvPoint x/y 点,提供默认和 (x,y) 构造
LvArea x1/y1/x2/y2 绝对区域
LvColor BGRA 分量或 full 颜色
LvImgHeader / LvImgDsc 图片头和像素数据描述
LvGradientStop / LvGradDsc 两段渐变描述
LvDrawRectDsc 矩形背景、图片、边框、外框、阴影
LvDrawArcDsc 圆弧绘制参数
LvDrawLabelDsc 文字绘制参数
LvDrawImgDsc 图片旋转、缩放、重着色
LvDrawLineDsc 直线、虚线和端帽
LvChartSeries / LvChartCursor 图表系列/光标内部映射
LvMeterScale / LvMeterIndicator 仪表标尺/指示器内部映射
LvStyleValue / LvStyleConstProp / LvStyle LVGL 样式内部映射

这些结构体直接映射特定 LVGL 版本 ABI。升级 LVGL 后字段顺序、位域和大小可能变化,不应用于持久化或网络传输,也不要跨不同编译版本共享二进制内存。

3.1 绘制描述符构造

cpp 复制代码
LvDrawRectDsc rect;
rect.bg_opa = 255;
rect.bg_color.full = 0x1687d9;

LvDrawArcDsc arc;
arc.width = 4;
arc.color.full = 0xff0000;

LvDrawLineDsc line;
line.width = 2;
line.color.full = 0x333333;

LvDrawRectDsc、LvDrawArcDsc、LvDrawLabelDsc、LvDrawLineDsc 有构造函数。

严重实现问题:无参 LvDrawLabelDsc() 调用 lv_memset_00(this, sizeof(LvDrawRectDsc)),使用了错误且通常更大的结构体大小,可能覆盖相邻内存。当前版本不要使用无参构造:

cpp 复制代码
// 避免:LvDrawLabelDsc dsc;

void* font = widget->getFont(18);
LvDrawLabelDsc dsc(font); // 使用显式字体构造

更稳妥的是使用原生 lv_draw_label_dsc_t 与 lv_draw_label_dsc_init,再在需要 STT 接口时确认布局兼容。

4. STTStyle 主对象

主属性:

方法 说明
setRadius / getRadius 圆角
setWidth 样式宽度
setClipCorner / getClipCorner 是否裁剪圆角外子内容
setOpa / getOpa 总体透明度
setBlendMode / getBlendMode 混合模式
setLayout / getLayout Flex/Grid 布局 ID
setBaseDir / getBaseDir LTR、RTL、Auto
setColorFilterOpa / getColorFilterOpa 状态颜色过滤透明度
add / remove 添加或删除 LvStyle
attach 重定向包装器到另一个 lv_obj
cpp 复制代码
widget->getStyle()
    ->setRadius(8)
    ->setOpa(255)
    ->setClipCorner(true)
    ->setBaseDir(0);

add/remove 使用的 LvStyle* 必须在附着期间持续有效。remove(nullptr, selector) 按 selector 移除匹配样式,默认是 Any part/Any state,影响范围很大。

公开子属性:

text 复制代码
p_bg, p_border, p_transform, p_img, p_outline,
p_pad, p_shadow, p_text, p_translate, p_line,
p_arc, p_anim, p_location, p_size, p_scrollbar

它们由 STTStyle 构造并析构,调用方不得 delete。

5. STTStyleSize

cpp 复制代码
auto* size = widget->getStyle()->p_size;
size->setWidth(200)
    ->setMinWidth(100)
    ->setMaxWidth(400)
    ->setHeight(80)
    ->setMinHeight(40)
    ->setMaxHeight(160);
size->setSize(64);

读取:getWidth、getMinWidth、getMaxWidth、getHeight、getMinHeight、getMaxHeight。

这些是“样式尺寸”,与 STTWidget::setWidth/setHeight 的直接对象尺寸语义不同。布局中最终结果受 min/max、百分比、content 和父布局共同影响。

6. STTStyleLocation

cpp 复制代码
auto* location = widget->getStyle()->p_location;
location->setX(10)->setY(20)->setAlign(ALIGN::CENTER);

int x = location->getX();
int y = location->getY();
int align = location->getAlign();

方法:setX、setY、setAlign、getX、getY、getAlign。它们操作 style x/y/align,不更新 STTWidget 的 mSetted 缓存。

7. STTStyleAnim

样式动画参数:

cpp 复制代码
auto* animStyle = widget->getStyle()->p_anim;
animStyle->setTime(500)->setSpeed(120);
int time = animStyle->getTime();
int speed = animStyle->getSpeed();

通用动画:

cpp 复制代码
static void applyX(void* target, int32_t value) {
    ((STTWidget*)target)->setX(value);
}

static void onDeleted(void* anim) {
    STTWidget* target =
        (STTWidget*)STTStyleAnim::getSTTWidget(anim);
}

void* handle = widget->getStyle()->p_anim->doAnim(
    widget,
    0, 200,
    500,
    applyX,
    onDeleted,
    0,
    0,
    0,
    3
);

pathcb:0 linear、1 ease in、2 ease out、3 ease in/out、4 overshoot、5 bounce、6 step。

repeat<0 无限。finishcb 实际被注册为 LVGL deleted callback,经 reinterpret_cast 后接收到的是 lv_anim_t*,不是 STTWidget*;通过 getSTTWidget 取 var。

cpp 复制代码
bool stopped = widget->getStyle()->p_anim->stopAnim(widget, handle);

handle 是 LVGL 管理的内部指针,动画删除后失效。传 nullptr 时按 var/空 exec_cb 删除第一个匹配动画,不一定是业务期望的那一个。

8. STTStyleArc

方法:

text 复制代码
setWidth, setRounded, setColor, setOpa, setImgSrc
getWidth, getRounded, getColor, getOpa, getImgSrc
cpp 复制代码
widget->getStyle()->p_arc
    ->setWidth(12, Part::Indic)
    ->setRounded(true, Part::Indic)
    ->setColor(0x1687d9, Part::Indic)
    ->setOpa(255, Part::Indic);

图片源为 const void*,必须符合 LVGL 图片源规则并保持有效。

9. STTStyleLine

方法:

text 复制代码
setWidth, setDashWidth, setDashGap, setRounded, setColor, setOpa
getWidth, getDashWidth, getDashGap, getRounded, getColor, getOpa
cpp 复制代码
widget->getStyle()->p_line
    ->setWidth(3)
    ->setDashWidth(8)
    ->setDashGap(4)
    ->setRounded(true)
    ->setColor(0x333333)
    ->setOpa(255);

斜线虚线在 LVGL 中可能受限制。

10. STTStyleShadow

方法:

text 复制代码
setWidth, setOfsX, setOfsY, setSpread, setColor, setOpa
getWidth, getOfsX, getOfsY, getSpread, getColor, getOpa
cpp 复制代码
widget->getStyle()->p_shadow
    ->setWidth(12)
    ->setOfsX(0)
    ->setOfsY(4)
    ->setSpread(1)
    ->setColor(0x000000)
    ->setOpa(80);

大阴影显著扩大重绘区域。

11. STTStyleOutline

方法:

text 复制代码
setWidth, setColor, setOpa, setPad
getWidth, getColor, getOpa, getPad
cpp 复制代码
widget->getStyle()->p_outline
    ->setWidth(2, WidgetState::FOCUSED)
    ->setColor(0x1687d9, WidgetState::FOCUSED)
    ->setOpa(255, WidgetState::FOCUSED)
    ->setPad(2, WidgetState::FOCUSED);

outline 不占布局尺寸,可能绘制到控件外。

12. STTStyleImg

方法:

text 复制代码
setOpa, setRecolor, setRecolorOpa
getOpa, getRecolor, getRecolorOpa
cpp 复制代码
widget->getStyle()->p_img
    ->setOpa(255)
    ->setRecolor(0xff0000)
    ->setRecolorOpa(100);

recolorOpa=0 保持原色,255 完全重着色。

13. STTStyleText

方法:

text 复制代码
setColor, setOpa, setFont, setLetterSpace, setLineSpace, setDecor, setAlign
getColor, getOpa, getFont, getLetterSpace, getLineSpace, getDecor, getAlign
cpp 复制代码
void* font = widget->getFont(18, "", 1);
widget->getStyle()->p_text
    ->setColor(0x222222)
    ->setOpa(255)
    ->setFont(font)
    ->setLetterSpace(1)
    ->setLineSpace(4)
    ->setDecor(0)
    ->setAlign(2);

setFont(nullptr) 静默不做任何事,不会恢复默认字体。字体指针必须持续有效。

14. STTStylePad

方法:

text 复制代码
setTop, setBottom, setLeft, setRight, setAll,
setRow, setColumn, setHor, setVer, setGap,
getTop, getBottom, getLeft, getRight, getRow, getColumn
cpp 复制代码
widget->getStyle()->p_pad
    ->setAll(8)
    ->setRow(6)
    ->setColumn(10);

setHor/setVer/setGap 是 LVGL 组合 setter,但没有对应组合 getter,读取用左右/上下/row/column。

15. STTStyleTranslate

方法:setX、setY、getX、getY。

cpp 复制代码
widget->getStyle()->p_translate
    ->setX(4, WidgetState::PRESSED)
    ->setY(2, WidgetState::PRESSED);

translate 影响绘制位置,不更新布局占位或 STTWidget 坐标缓存。

16. STTStyleTransform

方法:

text 复制代码
setWidth, setHeight, setAngle, setPivotX, setPivotY, setZoom
getWidth, getHeight, getAngle, getPivotX, getPivotY, getZoom
cpp 复制代码
widget->getStyle()->p_transform
    ->setPivotX(50)
    ->setPivotY(50)
    ->setAngle(30.0f)
    ->setZoom(1.2f)
    ->setWidth(4)
    ->setHeight(4);

角度内部乘 10,zoom 乘 256;get 使用相反换算。没有范围校验。

17. STTStyleBorder

方法:

text 复制代码
setColor, setOpa, setWidth, setSide, setPost
getColor, getOpa, getWidth, getSide, getPost
cpp 复制代码
widget->getStyle()->p_border
    ->setColor(0xcccccc)
    ->setOpa(255)
    ->setWidth(1)
    ->setSide(1 | 2 | 4 | 8)
    ->setPost(false);

side 位值为下 1、上 2、左 4、右 8。post 表示延后绘制边框。

18. STTStyleBg

写方法:

text 复制代码
setFromDsc, setColor, setOpa, setGradColor, setGradDir,
setMainStop, setGradStop, setImgSrc, setImgOpa,
setImgRecolor, setImgRecolorOpa, setImgTiled

读方法:

text 复制代码
getColor, getOpa, getGradColor, getGradDir,
getMainStop, getGradStop, getImgSrc, getImgOpa,
getImgRecolor, getImgRecolorFiltered, getImgRecolorOpa,
getImgTiled
cpp 复制代码
widget->getStyle()->p_bg
    ->setColor(0xffffff)
    ->setGradColor(0xe8f2ff)
    ->setGradDir(1)
    ->setMainStop(0.0f)
    ->setGradStop(1.0f)
    ->setOpa(255);

MainStop/GradStop 以 0.0..1.0 输入,内部乘 255,不做夹取。setFromDsc 只复制背景相关字段,不复制 radius、border、outline、shadow 等。

图片:

cpp 复制代码
widget->getStyle()->p_bg
    ->setImgSrc("res/bg.png")
    ->setImgOpa(255)
    ->setImgRecolor(0xffffff)
    ->setImgRecolorOpa(0)
    ->setImgTiled(false);

路径/描述符生命周期由调用方和 LVGL 资源系统负责。

19. STTStylePropScrollbar

配置与读取:

cpp 复制代码
auto* scroll = widget->getStyle()->p_scrollbar;
scroll->setMode(3);
scroll->setDir(12);
scroll->setSnapX(0);
scroll->setSnapY(3);

uint8_t mode = scroll->getMode();
uint8_t dir = scroll->getDir();
uint8_t snapX = scroll->getSnapX();
uint8_t snapY = scroll->getSnapY();

位置/范围:

cpp 复制代码
int x = scroll->getX();
int y = scroll->getY();
int top = scroll->getTop();
int bottom = scroll->getBottom();
int left = scroll->getLeft();
int right = scroll->getRight();

LvPoint end;
scroll->getEnd(&end);

滚动:

cpp 复制代码
scroll->scrollBy(20, 0, LV_ANIM_ON);
scroll->scrollTo(100, 0, LV_ANIM_OFF);
scroll->scrollToX(40, LV_ANIM_ON);
scroll->scrollToY(80, LV_ANIM_ON);
scroll->scrollToView(LV_ANIM_ON);
scroll->scrollToViewRecursive(LV_ANIM_ON);

辅助:

cpp 复制代码
bool active = scroll->isScrolling();
scroll->updateSnap(LV_ANIM_ON);

LvArea horizontal, vertical;
scroll->getArea(&horizontal, &vertical);
scroll->invalidate();
scroll->reAdjust(LV_ANIM_ON);

头文件对 reAdjust 的 anim_en 文案与 LVGL 常规枚举可能相反;实现直接强转 lv_anim_enable_t,应使用 LV_ANIM_OFF/ON 常量,不写 0/1 注释语义。

20. STTStyleProp 与 STTStyleHelper

STTStyleProp 是所有子属性基类:

text 复制代码
STTStyleProp(void* obj), attach(void* obj), selector, protected object

attach 只是替换底层 object,不校验类型/有效性。

STTStyleHelper:

cpp 复制代码
STTStyle* a = STTStyleHelper::attach(widget, 0);
STTStyle* b = STTStyleHelper::attach(rawLvObject, 1);

flag=0 把 obj 当 STTWidget* 并读取 object;非 0 直接当 lv_obj_t*。类型传错会崩溃。p_style 字段未用于返回实例管理。

21. STTLayout

cpp 复制代码
container->setLayout(STTLayout::FlexLayout());
STTLayout::setFlexFlow(container, 0);
STTLayout::setFlexAlign(container, 0, 0, 2, 0);
STTLayout::setFlexGlow(child, 0, 1);

API:

方法 说明
FlexLayout 返回 LV_LAYOUT_FLEX
GridLayout 返回 LV_LAYOUT_GRID
setFlexFlow(obj, style) obj 固定按 STTWidget*
setFlexFlow(obj, objtype, style) objtype=0 STTWidget,其他为 lv_obj_t
setFlexAlign 设置 main/cross/track 对齐
setFlexGlow 名称拼写为 Glow,实际调用 lv_obj_set_flex_grow

flow style:0 行、4 行换行、8 行反向、12 行换行反向;1 列、5 列换列、9 列反向、13 列换列反向。

GridLayout 只返回布局 ID,本头文件没有网格描述符配置封装,复杂 Grid 仍需 LVGL API。

22. 生产注意事项

  • 不缓存 getStyle/STTStyleHelper 返回值。
  • 不在多线程并发调用样式包装器。
  • 避免无参 LvDrawLabelDsc 构造。
  • selector 显式传给具体方法。
  • 颜色、透明度、角度、缩放和尺寸由调用方校验。
  • add 的 LvStyle、字体、图片源和动画目标必须保持有效。
  • 映射结构体只适配当前 LVGL ABI。
  • 频繁阴影、变换和透明混合会增加真机绘制负载。
最近修改: 2026-10-21Powered by