组件库开发
2025-07-17
组件库介绍
当业务需求实现一整套统一样式风格的GUI样式库时,可以使用组件库的形式对相同样式风格的组件进行统一管理,方便后期扩展及维护。未来tinyPiXOS会提供各种样式风格的组件库,并以当前规范进行发布。
目录结构创建
组件库开发需要遵循目录结构规范,将组件库的头文件、源码文件、构建文件等分类放入指定文件夹。并且需要创建 FrameworkGlobal.h 放置组件库全局定义,及命名空间声明。目录结构规范如下:
在tinyPiXCore
PiXGUIFramework
exampleGUI
CMakeList.txt
CMakePresets.json
src
include
GUIFramework
exampleGUI
widgets
testLight.h
FrameworkGlobal.h
src
GUIFramework
exampleGUI
widgets
testLight.cpp
定义框架命名空间
编辑FrameworkGlobal.h
FrameworkGlobal.h
#ifndef _EXAMPLE_GUI_GLOBAL_H
#define _EXAMPLE_GUI_GLOBAL_H
#define EXAMPLE_GUI_NAMESPACE_BEGIN namespace exampleGUI {
#define EXAMPLE_GUI_NAMESPACE_END }
#endif
重构testLight类
使用PIMPL隐藏设计实现
testLight.h
#ifndef __TEST_LIGHT_H
#define __TEST_LIGHT_H
#include "tpChildWidget.h"
#include "tpEvent.h"
#include "FrameworkGlobal.h"
EXAMPLE_GUI_NAMESPACE_BEGIN
TP_DEF_VOID_TYPE_VAR(ItestLightData);
class testLight : public tpChildWidget
{
public:
testLight(tpChildWidget *parent);
virtual ~testLight();
public:
virtual bool onMouseKeyEvent(tpMouseKeyEvent *event) override;
virtual bool onPaintEvent(tpObjectPaintEvent *event) override;
private:
ItestLightData *data_;
};
EXAMPLE_GUI_NAMESPACE_END
#endif
testLight.cpp
#include "testLight.h"
#include "tpCanvas.h"
EXAMPLE_GUI_NAMESPACE_BEGIN
struct testLightData
{
int maxCount_;
int count_;
testLightData() : maxCount_(0), count_(0)
{
}
};
testLight::testLight(tpChildWidget *parent)
: tpChildWidget(parent)
{
testLightData *lightData = new testLightData();
lightData->maxCount_ = 4;
lightData->count_ = 0;
data_ = lightData;
}
testLight::~testLight()
{
testLightData *lightData = static_cast<testLightData *>(data_);
if (lightData)
{
delete lightData;
lightData = nullptr;
data_ = nullptr;
}
}
bool testLight::onMouseKeyEvent(tpMouseKeyEvent *event)
{
tpChildWidget::onMouseKeyEvent(event);
if (event->button() == BUTTON_LEFT)
{
if (event->state())
{
testLightData *lightData = static_cast<testLightData *>(data_);
lightData->count_++;
if (lightData->count_ > lightData->maxCount_)
lightData->count_ = 0;
}
}
return true;
}
bool testLight::onPaintEvent(tpObjectPaintEvent *event)
{
tpChildWidget::onPaintEvent(event);
testLightData *lightData = static_cast<testLightData *>(data_);
tpCanvas *painter = event->canvas();
painter->box(0, 0, width(), height(), _RGB(255, 255, 255));
int spacing = 3;
int singleWidth = (width() - (lightData->maxCount_ + 1) * spacing) / lightData->maxCount_;
for (int i = 0; i < lightData->count_; ++i)
{
int drawX = spacing + i * (singleWidth + spacing);
painter->box(drawX, spacing, drawX + singleWidth, height() - spacing, _RGB(128, 255, 128));
}
return true;
}
EXAMPLE_GUI_NAMESPACE_END
测试使用
CMakeList引入exampleGUI头文件目录和引入动态库引用
include_directories(/usr/include/tinyPiX/GUIFramework)
target_link_libraries(examplesApp exampleGUI)
为防止多个UI框架头文件重复导致引用异常,请使用UI框架的父级目录引入。
#include"exampleGUI/widgets/testLight.h"
使用方式同上一节自定义组件
注:需添加命名空间引入
exampleGUI::testLight* light = new exampleGUI::testLight(this);
testButton_->setSize(200, 50);
testButton_->move(150, 300);