qt之led(点阵)控件类设计

推荐文章:

1、效果展示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2、设计思路

新建普通类并继承QWidget属性(个人偏好,不带ui文件),并重写绘制事件,绘制led显示形状和颜色。
其实如果只是显示led亮/灭状态,实现方式有很多,比如插图方式,显示既美观,代码量又少,但是我们需要显示三原色、多彩且可亮度调节的led,所以这里使用重绘方式进行设计。
定义功能接口:(个人觉得,首先将接口合理定义、明确,后面代码实现的工作效率将很高)

  1. 可设置led形状,可现实方形(有方形led点阵)和圆形,可增加其他形状,有需要的自定义设计。
	void setShape(LedShape shape);
	void setShapeToCir();       //设置灯为圆状
	void setShapeToSqu();       //设置灯为方状
  1. 设置led三原色显示,即可显示任意颜色。
	void setColor(QColor color);    //设置led颜色
	void setColor(unsigned char red, unsigned char green, unsigned char blue);
	QColor getLedColor();   //获取led颜色
  1. 可设置led灯大小,大小是否可随窗口变化。
    //设置led灯大小,此处为绝对大小,即限制了最大最小,直接固定在一个一个大小
    void setFixedSize(int width, int hight); //设置led大小
    void unFixedSize(int miniWidth = 0,int miniHight = 0);  //取消固定大小,一般不建议使用。
  1. 设置是否点亮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);
    }
}
  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值