推荐文章:
- qt电池控件设计:https://blog.csdn.net/weixin_42887343/article/details/113932145
- QWidget控件拖动:https://blog.csdn.net/weixin_42887343/article/details/114384324
- QWidget控件旋转方法:https://blog.csdn.net/weixin_42887343/article/details/115037420
- qt淡化提示框设计:https://blog.csdn.net/weixin_42887343/article/details/109303972
- qt之led(点阵)控件类设计:https://blog.csdn.net/weixin_42887343/article/details/115348953
- 加载动画控件类设计:https://blog.csdn.net/weixin_42887343/article/details/118541411
- 环形进度条控件设计:https://blog.csdn.net/weixin_42887343/article/details/120222293
1、效果展示
2、设计思路
新建普通类并继承QWidget属性(个人偏好,不带ui文件),并重写绘制事件,绘制led显示形状和颜色。
其实如果只是显示led亮/灭状态,实现方式有很多,比如插图方式,显示既美观,代码量又少,但是我们需要显示三原色、多彩且可亮度调节的led,所以这里使用重绘方式进行设计。
定义功能接口:(个人觉得,首先将接口合理定义、明确,后面代码实现的工作效率将很高)
- 可设置led形状,可现实方形(有方形led点阵)和圆形,可增加其他形状,有需要的自定义设计。
void setShape(LedShape shape);
void setShapeToCir(); //设置灯为圆状
void setShapeToSqu(); //设置灯为方状
- 设置led三原色显示,即可显示任意颜色。
void setColor(QColor color); //设置led颜色
void setColor(unsigned char red, unsigned char green, unsigned char blue);
QColor getLedColor(); //获取led颜色
- 可设置led灯大小,大小是否可随窗口变化。
//设置led灯大小,此处为绝对大小,即限制了最大最小,直接固定在一个一个大小
void setFixedSize(int width, int hight); //设置led大小
void unFixedSize(int miniWidth = 0,int miniHight = 0); //取消固定大小,一般不建议使用。
- 设置是否点亮led灯,以及设置未点亮状态下led颜色,一般为灰黑色。
bool isLight(); //判断是否点亮
void setLight(bool light = true); //设置是否点亮
void setUnlightColor(QColor color = QColor(50,50,50)); //设置未点亮状态下颜色
3、源代码
此源代码为单个led类,如需要实现led点阵,可查看后文demo部分。
h文件
#ifndef RGBLED_H
#define RGBLED_H
#include <QWidget>
#include <QPainter>
enum LedShape
{
circular,
square,
};
class RGBLed : public QWidget
{
Q_OBJECT
public:
explicit RGBLed(QWidget *parent = nullptr);
void setShape(LedShape shape);
void setShapeToCir(); //设置灯为圆状
void setShapeToSqu(); //设置灯为方状
void setColor(QColor color); //设置led颜色
void setColor(unsigned char red, unsigned char green, unsigned char blue);
QColor getLedColor(); //获取led颜色
//设置led灯大小,此处为绝对大小,即限制了最大最小,直接固定在一个一个大小
void setFixedSize(int width, int hight); //设置led大小
void unFixedSize(int miniWidth = 0,int miniHight = 0); //取消固定大小,一般不建议使用。
//led有两种状态,一种是点亮状态,正常显示设置的颜色,第二种是未点亮(熄灭)的状态,熄灭状态的颜色也可以设置,一般为黑灰色。
bool isLight(); //判断是否点亮
void setLight(bool light = true); //设置是否点亮
void setUnlightColor(QColor color = QColor(50,50,50)); //设置未点亮状态下颜色
//hsv格式转rgb格式,静态模式,外界可直接使用
static void HSVtoRGB(unsigned char *r, unsigned char *g, unsigned char *b, int h, int s, int v);
signals:
private:
void paintEvent(QPaintEvent *paintEvent) override;
void mouseReleaseEvent(QMouseEvent *event) override;
QColor mColor; //led灯颜色
LedShape mShape; //led灯形状
bool lightFlag; //灯是否点亮
QColor unlightColor; //熄灭状态的颜色,默认(50,50,50)
};
#endif // RGBLED_H
cpp文件
#include "rgbled.h"
RGBLed::RGBLed(QWidget *parent) :
QWidget(parent)
,mShape(square)
,lightFlag(true)
,unlightColor(QColor(50,50,50))
{
setFixedSize(30,30);
mColor = unlightColor;
}
void RGBLed::setShape(LedShape shape)
{
mShape = shape;
}
void RGBLed::setShapeToCir()
{
mShape = circular;
}
void RGBLed::setShapeToSqu()
{
mShape = square;
}
void RGBLed::setFixedSize(int width,int hight)
{
this->setMaximumSize(width,hight);
this->setMinimumSize(width,hight);
update();
}
void RGBLed::unFixedSize(int miniWidth, int miniHight)
{
this->setMaximumSize(10000,10000);
this->setMinimumSize(miniWidth,miniHight);
}
bool RGBLed::isLight()
{
return lightFlag;
}
void RGBLed::setLight(bool light)
{
lightFlag = light;
}
void RGBLed::setUnlightColor(QColor color)
{
unlightColor = color;
}
void RGBLed::setColor(QColor color)
{
mColor = color;
update();
}
void RGBLed::setColor(unsigned char red,unsigned char green,unsigned char blue)
{
mColor = QColor(red,green,blue);
update();
}
QColor RGBLed::getLedColor()
{
return mColor;
}
void RGBLed::paintEvent(QPaintEvent *paintEvent)
{
Q_UNUSED(paintEvent);
QPainter painter(this);
int edgeWidth = 1;
int width = this->width();
int hight = this->height();
painter.setPen(QPen(QColor(255, 255, 255)));
QBrush brush(QColor(255,255,255));
painter.setBrush(brush);
//绘制中心显色区域
if(lightFlag)
painter.setBrush(mColor);
else
painter.setBrush(unlightColor);
if(mShape == square)
painter.drawRect(QRectF(edgeWidth, edgeWidth, width-edgeWidth, hight-edgeWidth));
else if(mShape == circular)
painter.drawEllipse(QRectF(edgeWidth, edgeWidth, width-edgeWidth, hight-edgeWidth));
painter.end();
}
void RGBLed::mouseReleaseEvent(QMouseEvent *event)
{
lightFlag = !lightFlag;
update();
}
void RGBLed::HSVtoRGB(unsigned char *r, unsigned char *g, unsigned char *b, int h, int s, int v)
{
// convert from HSV/HSB to RGB color
// R,G,B from 0-255, H from 0-260, S,V from 0-100
// ref http://colorizer.org/
// The hue (H) of a color refers to which pure color it resembles
// The saturation (S) of a color describes how white the color is
// The value (V) of a color, also called its lightness, describes how dark the color is
int i;
float RGB_min, RGB_max;
RGB_max = v*2.55f;
RGB_min = RGB_max*(100 - s)/ 100.0f;
i = h / 60;
int difs = h % 60; // factorial part of h
float RGB_Adj = (RGB_max - RGB_min)*difs / 60.0f; // RGB adjustment amount by hue
switch (i) {
case 0:
*r = RGB_max;
*g = RGB_min + RGB_Adj;
*b = RGB_min;
break;
case 1:
*r = RGB_max - RGB_Adj;
*g = RGB_max;
*b = RGB_min;
break;
case 2:
*r = RGB_min;
*g = RGB_max;
*b = RGB_min + RGB_Adj;
break;
case 3:
*r = RGB_min;
*g = RGB_max - RGB_Adj;
*b = RGB_max;
break;
case 4:
*r = RGB_min + RGB_Adj;
*g = RGB_min;
*b = RGB_max;
break;
default: // case 5:
*r = RGB_max;
*g = RGB_min;
*b = RGB_max - RGB_Adj;
break;
}
}
4、demo设计
1、mainwindows的ui界面中添加格栅布局,如下图:
为什么要使用格栅布局,因为作为demo,这里我尽可能展示设计led类的最初目的——led点阵显示,而且效果展示不也是显示点阵。
2、mainwindows构造函数添加代码:
for(int i = 0;i < 256;i ++)
{
RGBLed *led = new RGBLed(this);
ledList.append(led);
led->setShapeToCir();
led->setUnlightColor(QColor(0,0,0));
ui->gridLayout->addWidget(led,i/16,i%16);
}
QTimer *mtime = new QTimer;
connect(qtime,&QTimer::timeout,this,[=]()
{
testLed();
});
mtime->start(100);
记住,再mainwindows类中添加led控件的指针链表,后续操作和释放内存都需要。
QList<RGBLed *> ledList;
测试函数如下:
void MainWindow::testLed()
{
static unsigned char offset = 0;
offset = offset+3;
for(int i = 0;i < 256;i ++)
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char h = i+offset;
RGBLed::HSVtoRGB(&r,&g,&b,h,100,75);
ledList.at(i)->setColor(r,g,b);
}
}