当前位置: 首页 > news >正文

不止是进度条:深入PiXSingleGUI的TpSlideProgressBar组件架构设计​

组件运行效果展示

TpSlideProgressBar

TpSlideProgressBar 组件概述

TpSlideProgressBar是TinyPiXOS系统中专门用于交互式进度控制的GUI组件,属于PiXSingleGUI库的标准化控件之一。该组件继承自TpChildWidget基类,遵循PiXSingleGUI的统一架构设计。

核心架构设计

继承关系与基类依赖

TpSlideProgressBar继承自TpChildWidget,这确保了它具备完整的GUI组件能力,包括事件处理、渲染管理和生命周期控制。

数据结构设计

组件采用PIMPL(Private Implementation)设计模式,通过TpSlideProgressBarData结构体封装内部数据 TpSlideProgressBar.cpp:6-24

struct TpSlideProgressBarData
{int32_t minValue = 0;int32_t maxValue = 0;double curValue = 0;TpShared<TpSurface> iconSurface;ItpPoint pressPoint;bool mouseLeftPress = false;TpSlideProgressBarData() : iconSurface(TpMakeShared<TpSurface>()){}~TpSlideProgressBarData(){}
};

核心数据成员包括:

  • minValue/maxValue:进度条的值范围控制
  • curValue:当前进度值
  • iconSurface:图标显示资源
  • pressPoint/mouseLeftPress:鼠标交互状态追踪

功能实现详解

进度值管理

组件提供了完整的进度值管理接口,支持自定义范围的进度控制TpSlideProgressBar.cpp:53-64

void TpSlideProgressBar::setRange(const int32_t &minValue, const int32_t &maxValue)
{TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);progressData->minValue = minValue;progressData->maxValue = maxValue;if (progressData->maxValue <= progressData->minValue){progressData->maxValue = progressData->minValue + 1;}
}

进度设置时会自动进行边界检查,确保数值在有效范围内,并触发界面更新和信号发射TpSlideProgressBar.cpp:66-82

void TpSlideProgressBar::setValue(const int32_t &value)
{TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);progressData->curValue = value;if (progressData->curValue < progressData->minValue)progressData->curValue = progressData->minValue;else if (progressData->curValue > progressData->maxValue)progressData->curValue = progressData->maxValue;else{}onValueChanged.emit(progressData->curValue);update();
}

交互式拖拽机制

组件实现了完整的鼠标交互处理链:

鼠标按下事件记录交互状态 TpSlideProgressBar.cpp:104-117

bool TpSlideProgressBar::onMousePressEvent(TpMouseEvent *event)
{TpChildWidget::onMousePressEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (event->button() == BUTTON_LEFT){progressData->mouseLeftPress = event->state();progressData->pressPoint = event->globalPos();}return true;
}

拖拽过程中实时计算进度值 TpSlideProgressBar.cpp:133-163

bool TpSlideProgressBar::onMouseMoveEvent(TpMouseEvent *event)
{TpChildWidget::onMouseMoveEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (progressData->mouseLeftPress){ITpPoint curPos = event->globalPos();int32_t offsetX = curPos.x - progressData->pressPoint.x;progressData->pressPoint = curPos;// value偏移对应像素  (1.0 / (100 - 0))// double curValue = value() + (1.0 * offsetX) / ((width() - 4) / (progressData->maxValue - progressData->minValue));// setValue(curValue);progressData->curValue += (1.0 * offsetX) / ((width() - 4) / (progressData->maxValue - progressData->minValue));if (progressData->curValue < progressData->minValue)progressData->curValue = progressData->minValue;else if (progressData->curValue > progressData->maxValue)progressData->curValue = progressData->maxValue;else{}onValueChanged.emit(progressData->curValue);update();// std::cout << "progressData->curValue  " << progressData->curValue << std::endl;}return true;
}

鼠标释放事件清理交互状态 TpSlideProgressBar.cpp:119-131

bool TpSlideProgressBar::onMouseRleaseEvent(TpMouseEvent *event)
{TpChildWidget::onMouseRleaseEvent(event);TpSlideProgressBarData *progressData = static_cast<TpSlideProgressBarData *>(data_);if (event->button() == BUTTON_LEFT){progressData->mouseLeftPress = event->state();}return true;
}

信号槽通信

组件通过onValueChanged信号提供值变化事件通知 TpSlideProgressBar.h:37 ,实现与外部系统的解耦通信。

declare_signal(onValueChanged, int32_t);

绘制渲染逻辑

onPaintEvent方法实现了完整的进度条图形绘制逻辑TpSlideProgressBar.cpp:183-229

绘制过程包括:

进度填充:根据当前进度值计算填充宽度并绘制圆角填充区域 TpSlideProgressBar.cpp:193-209

// 绘制填充
double valuePercent = 1.0 * (progressData->curValue - progressData->minValue) / (progressData->maxValue - progressData->minValue);uint32_t valueWidth = valuePercent * (width() - 4);
if (valueWidth > width())valueWidth = width();if (valueWidth > 0)
{// uint32_t minRad = (valueWidth > (height() - 4) ? (height() - 4) : valueWidth) * roundCorners();double minRad = 1.0 * roundCorners() / height();minRad *= (height() - 4 - 2);// paintCanvas->roundedBox(2, 2,  valueWidth - 4, height() - 4, minRad, curCssData->color());paintCanvas->roundedBox(2, 2, 2 + valueWidth, height() - 4, minRad, curCssData->color());
}

图标渲染:支持自定义图标的缩放显示 TpSlideProgressBar.cpp:211-226

// 绘制图标
if (progressData->iconSurface->hasSurface())
{TpShared<TpSurface> drawSurface = progressData->iconSurface->scaled(curCssData->iconSize(), curCssData->iconSize());if (!drawSurface)return true;int32_t imageWidth = drawSurface->width();int32_t imageHeight = drawSurface->height();TpCanvas *canvas = event->canvas();int32_t cy = (rect().h - imageHeight) / 2;paintCanvas->paintSurface(cy, cy, drawSurface);
}

样式系统集成

TpSlideProgressBar完全集成了PiXSingleGUI的CSS样式系统。在系统主题配置中,可以看到针对TpSlideProgressBar的样式定义purple-light.css:81-88

TpSlideProgressBar {height: 64dp;width: 305dp;icon-size: 33dp;background: rgba(0, 0, 0, 0.3);color: rgba(255, 255, 255, 1);border-radius: 16;
}

样式系统支持:

  • height/width:组件尺寸配置
  • icon-size:图标尺寸设置
  • background/color:背景和填充颜色配置
  • border-radius:圆角边框设置

系统集成与应用场景

TpSlideProgressBar作为通用交互式进度控制组件,可广泛应用于:

  1. 音频/视频播放器的进度控制
  2. 系统设置中的参数调节滑块
  3. 多媒体应用的时间轴操作
  4. 任何需要用户交互式调节数值的场景

演示程序

#include "TpApp.h"
#include "TpFixScreen.h"
#include "TpLabel.h"
#include "TpSlideProgressBar.h"
#include "TpFont.h"int32_t main(int32_t argc, char *argv[])
{TpApp app(argc, argv);TpFixScreen *vScreen = new TpFixScreen();vScreen->setBackGroundColor(_RGBA(128, 128, 128, 255));vScreen->setVisible(true); // vScreen setvisible will be update displayapp.bindVScreen(vScreen);TpLabel *valueText = new TpLabel(vScreen);valueText->setText(TpString::number(100));valueText->setAlign(tinyPiX::AlignCenter);valueText->font()->setFontColor(_RGB(255, 255, 255),_RGB(255, 255, 255));valueText->font()->setFontSize(128);valueText->setWidth(600);valueText->setHeight(400);valueText->move(100, 100);TpSlideProgressBar *slider = new TpSlideProgressBar(vScreen);slider->setRange(0, 100);slider->setValue(100);slider->move(100, 60);slider->setIcon("/opt/tinyPiXCore/examples/SingleGUI/TpSlideProgressBar/liangdu.svg");TpSlideProgressBar *vSlider = new TpSlideProgressBar(vScreen);vSlider->setRange(0, 100); vSlider->setValue(0);vSlider->move(100, 400);vSlider->setIcon("/opt/tinyPiXCore/examples/SingleGUI/TpSlideProgressBar/yinliang.svg");connect(slider, onValueChanged, [=](int32_t value){ valueText->setText(TpString::number(value));vSlider->setValue(100-value); });connect(vSlider, onValueChanged, [=](int32_t value){ valueText->setText(TpString::number(value));slider->setValue(100-value); });vScreen->update();return app.run();
}

TinyPiXOS开发者联盟

源码级支持 + 真实项目:TinyPiXOS开发者联盟招募中​,国产自主轻量级嵌入式设备桌面操作系统交流社群。
获取开发资料
官网网站
B 站视频

感谢支持和关注,如果对项目感兴趣,请点赞、收藏和转发!


文章转载自:

http://u23WaIRO.Lynmt.cn
http://UWoJ9Zvu.Lynmt.cn
http://R0ZCVcLd.Lynmt.cn
http://TQWbRy4V.Lynmt.cn
http://SOBxljv2.Lynmt.cn
http://cpDBB9Fd.Lynmt.cn
http://XXO8SAFu.Lynmt.cn
http://mDqG147S.Lynmt.cn
http://dyRo9hqc.Lynmt.cn
http://uDiVUkVc.Lynmt.cn
http://BHm76o2F.Lynmt.cn
http://0KxjAHy3.Lynmt.cn
http://LkglXttF.Lynmt.cn
http://Vq57th54.Lynmt.cn
http://4fXy38wG.Lynmt.cn
http://uPsBAWRo.Lynmt.cn
http://GhLiZQFW.Lynmt.cn
http://3xWIGVbi.Lynmt.cn
http://BBalhRRe.Lynmt.cn
http://0tubPhPu.Lynmt.cn
http://7rAH8KCm.Lynmt.cn
http://N4b6YZjd.Lynmt.cn
http://oXOHOWQq.Lynmt.cn
http://3WcLVtWh.Lynmt.cn
http://dlG0Alt1.Lynmt.cn
http://IpBlINB4.Lynmt.cn
http://dA48XqzR.Lynmt.cn
http://oEK9FDwQ.Lynmt.cn
http://tpwcS54c.Lynmt.cn
http://mDD6wCda.Lynmt.cn
http://www.dtcms.com/a/376404.html

相关文章:

  • Flutter 视频播放器——flick_video_player 介绍与使用
  • 【Java】Hibernate管理Session
  • 【ARMv7】系统复位上电后的程序执行过程
  • Ubuntu引导修复
  • PetaLinux_User_udev
  • 《链表的优雅封装:C++ list 模拟实现与迭代器之美》
  • 基于Redis设计一个高可用的缓存
  • 看涨看跌期权平价公式原理及其拓展
  • Django 基础入门:命令、结构与核心配置全解析
  • 中断系统介绍
  • 算法题 Day5---String类(2)
  • 关于Linux系统调试和性能优化技巧有哪些?
  • 大数据电商流量分析项目实战:Hadoop初认识+ HA环境搭建(二)
  • 软考中级习题与解答——第四章_软件工程(2)
  • AutoTrack-IR-DR200底盘仿真详解:为教育领域打造的高效机器人学习实验平台
  • 介绍 Python Elasticsearch Client 的 ES|QL 查询构建器
  • LeetCode 234. 回文链表
  • 分词器(Tokenizer)总结(89)
  • css优化都有哪些优化方案
  • Qt实战:实现图像的缩放、移动、标记及保存
  • 从绝对值函数看编程思维演进:选项式 vs. 组合式
  • 内网环境下ubuntu 20.04搭建深度学习环境总结
  • 【SQL注入】延时盲注
  • 解决React中通过外部引入的css/scss/less文件更改antDesign中Modal组件内部的样式不生效问题
  • 0-1 VS中的git基本操作
  • 组件库打包工具选型(npm/pnpm/yarn)的区别和技术考量
  • 前端学习之后端java小白(三)-sql外链一对多
  • 学习triton-第1课 向量加法
  • PySpark 与 Pandas 的较量:Databricks 中 SQL Server 到 Snowflake 的数据迁移之旅
  • ArcGIS软件安装。