QT自定义指示灯(可闪烁、可移动)

        指示灯的应用场景很广泛,随着科技的进步和创新,指示灯的应用也在不断扩展和改进。指示灯在用户界面中常用于表示状态、警告或提示信息。在Qt中,可以通过自定义继承QWidget的类来实现自定义指示灯控件。本文将介绍实现两种形式。1、使用QPixmap绘制指示灯;2、在paintEvent中使用QPainter来绘制。

一、简述

         QT自定义指示灯控件。要实现自定义指示灯控件,首先需要创建一个自定义的QWidget类,并在这个类中重写绘图事件(paintEvent)。在paintEvent中,可以使用QT提供的绘图函数来绘制指示灯的外观。可以根据不同的状态设置不同的颜色、形状或图标等。

二、 设计思路    
  1. 创建一个QWidget子类Lamp作为指示灯的基类。
  2. 在Lamp类中,定义指示灯的常规属性。
  3. 创建一个Lamp的子类ImageLamp,重写paintEvent()函数,使用QPixmap绘制指示灯。(以图片的形式绘制)
  4. 创建一个Lamp的子类RoundLamp,重写paintEvent()函数,使用QPainter绘制指示灯。(纯代码绘制)
三、效果 

 

四、核心代码  
1、头文件

        lamp.h 

#ifndef LAMP_H
#define LAMP_H

#include <QWidget>
#include <QTimer>
#include <QPainter>

class Lamp : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(bool state MEMBER m_state);
    Q_PROPERTY(bool showText MEMBER m_showText);
    Q_PROPERTY(QString text MEMBER m_text);
    Q_PROPERTY(QColor textColor MEMBER m_textColor);
    Q_PROPERTY(bool canMove MEMBER m_canMove);
    Q_PROPERTY(bool canTick MEMBER m_canTick);
    Q_PROPERTY(int tickTime MEMBER m_tickTime);
public:
    explicit Lamp(QWidget *parent = nullptr);
    virtual ~Lamp();

    void setState(bool state);
    void setText(QString text);
    void setCanMove(bool canMove);
    void setCanTick(bool canTick);

protected:
    virtual void setTickTime(int tickTime) = 0;
    bool eventFilter(QObject * watched,QEvent * event);
    void upText(QPainter *p);

public:
    bool m_state;//状态——是否点亮
    bool m_showText;//是否显示文字
    QString m_text;//指示灯文本文字
    QFont m_textFont;
    QColor m_textColor;
    bool m_canMove;//是否可移动
    bool m_canTick;//是否闪烁
    bool m_tickState;
    int m_tickTime;//闪烁周期,毫秒
    QTimer m_tickTimer;
};

#endif // LAMP_H

imagelamp.h 

#ifndef IMAGELAMP_H
#define IMAGELAMP_H

#include "lamp.h"

class ImageLamp : public Lamp
{
    Q_OBJECT
public:
    explicit ImageLamp(QPixmap pixOn,QPixmap pixOff,QWidget *parent = nullptr);
    ~ImageLamp();   

protected:
    void paintEvent(QPaintEvent *event) override;
    void setTickTime(int tickTime) override;
    void upPixmap(QPainter *p);

public:
    QPixmap m_pixOn;
    QPixmap m_pixOff;
};

#endif // IMAGELAMP_H

roundlamp.h 

#ifndef ROUNDLAMP_H
#define ROUNDLAMP_H

#include "lamp.h"

class RoundLamp : public Lamp
{
    Q_OBJECT
public:
    explicit RoundLamp(QWidget *parent = nullptr);
    ~RoundLamp();

    void setOnColor(QColor onColor);

protected:
    void paintEvent(QPaintEvent *event) override;
    void setTickTime(int tickTime) override;
    void upFrameOut(QPainter *p,int r);
    void upFrameIn(QPainter *p,int r);
    void upLampColor(QPainter *p,int r);

public:
    QColor m_onColor;
    QColor m_offColor;
};

#endif // ROUNDLAMP_H
2、实现代码

lamp.cpp 

#include "lamp.h"
#include <QEvent>
#include <QMouseEvent>

Lamp::Lamp(QWidget *parent) : QWidget(parent)
{
    m_state=false;
    m_showText=true;
    m_textColor=QColor(0,0,0);
    m_textFont=QFont(QStringLiteral("宋体"));
    m_textFont.setPixelSize(20);
    m_text.clear();
    m_canMove=true;
    m_canTick=false;
    m_tickTime=1000;
    m_tickState=false;

    this->installEventFilter(this);
}

Lamp::~Lamp()
{

}

bool Lamp::eventFilter(QObject * watched, QEvent * event)
{
    if(!m_canMove)
        return QWidget::eventFilter(watched, event);

    static QPoint startPoint;
    static bool isMove;
    static int dx,dy;
    if(event->type()==QEvent::MouseButtonPress)
    {
        auto mouseEvent=static_cast<QMouseEvent *>(event);
        if (this->rect().contains(mouseEvent->pos()) && (mouseEvent->button() == Qt::LeftButton))
        {
            startPoint=mouseEvent->pos();
            isMove=true;
        }
    }
    else if(event->type()==QEvent::MouseMove&&isMove)
    {
        auto mouseEvent=static_cast<QMouseEvent *>(event);
        dx=mouseEvent->pos().x()-startPoint.x();
        dy=mouseEvent->pos().y()-startPoint.y();
        this->move(this->x()+dx,this->y()+dy);
    }
    else if(event->type()==QEvent::MouseButtonRelease&&isMove)
    {
        isMove=false;
    }
    return QWidget::eventFilter(watched, event);
}

void Lamp::upText(QPainter *p)
{
    if(!m_showText | m_text.isEmpty())
        return;

    int r=100;
    QRect rect(-r,-r,2*r,2*r);
    p->save();
    p->setPen(m_textColor);
    p->setFont(m_textFont);
    p->drawText(rect,Qt::AlignCenter,m_text);
    p->restore();
    update();
}

void Lamp::setState(bool state)
{
    m_state = state;
    update();
}

void Lamp::setText(QString text)
{
    m_text = text;
    update();
}

void Lamp::setCanMove(bool canMove)
{
    m_canMove = canMove;
}

void Lamp::setCanTick(bool canTick)
{
    m_canTick = canTick;
}

imagelamp.cpp  

#include "imagelamp.h"

ImageLamp::ImageLamp(QPixmap pixOn,QPixmap pixOff,QWidget *parent) : Lamp(parent)
{
    setFixedSize(50,50);

    m_pixOn = pixOn;
    m_pixOff = pixOff;

    setTickTime(m_tickTime);
}

ImageLamp::~ImageLamp()
{

}

void ImageLamp::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    int width=this->width();
    int height=this->height();

    QPainter p(this);
    p.translate(width/2,height/2);
    p.scale(width/200.0,height/200.0);
    p.setPen(Qt::NoPen);

    if(m_canTick&&(!m_tickTimer.isActive()))
        m_tickTimer.start(m_tickTime);
    else if(!m_canTick&&m_tickTimer.isActive())
        m_tickTimer.stop();

    upPixmap(&p);
    upText(&p);
}

void ImageLamp::upPixmap(QPainter *p)
{
    int r=100;
    p->save();

    if(m_state)
    {
        if(m_canTick)
        {
            if(m_tickState)
                p->drawPixmap(-r,-r,2*r,2*r,m_pixOn);
            else
                p->drawPixmap(-r,-r,2*r,2*r,m_pixOff);
        }
        else
            p->drawPixmap(-r,-r,2*r,2*r,m_pixOn);
    }
    else
        p->drawPixmap(-r,-r,2*r,2*r,m_pixOff);

    p->restore();
    update();
}

void ImageLamp::setTickTime(int tickTime)
{
    m_tickTimer.setInterval(tickTime);
    connect(&m_tickTimer,&QTimer::timeout,this,[this]{
        if(m_tickState)
            m_tickState=false;
        else
            m_tickState=true;
    });
}

roundlamp.cpp

#include "roundlamp.h"

RoundLamp::RoundLamp(QWidget *parent) : Lamp(parent)
{
    setFixedSize(50,50);

    m_onColor=QColor("green");
    m_offColor=QColor(125,125,125);

    setTickTime(m_tickTime);
}

RoundLamp::~RoundLamp()
{

}

void RoundLamp::upFrameOut(QPainter *p,int r)
{
    p->save();
    QLinearGradient gradient(0,-r,0,r);
    gradient.setColorAt(1,QColor(166,166,166));
    gradient.setColorAt(0,QColor(255,255,255));
    gradient.setSpread(QGradient::PadSpread);
    p->setBrush(gradient);
    p->drawEllipse(-r,-r,2*r,2*r);
    p->restore();
    update();
}

void RoundLamp::upFrameIn(QPainter *p, int r)
{
    p->save();
    QLinearGradient gradient(0,-r,0,r);
    gradient.setColorAt(0,QColor(166,166,166));
    gradient.setColorAt(1,QColor(255,255,255));
    gradient.setSpread(QGradient::PadSpread);
    p->setBrush(gradient);
    p->drawEllipse(-r,-r,2*r,2*r);
    p->restore();
    update();
}

void RoundLamp::upLampColor(QPainter *p,int r)
{
    p->save();
    if(m_state)
    {
        if(m_canTick)
        {
            if(m_tickState) p->setBrush(m_onColor);
            else p->setBrush(m_offColor);
        }
        else p->setBrush(m_onColor);
    }
    else p->setBrush(m_offColor);
    p->drawEllipse(-r,-r,2*r,2*r);
    p->restore();
    update();
}

void RoundLamp::setTickTime(int tickTime)
{
    m_tickTimer.setInterval(tickTime);
    connect(&m_tickTimer,&QTimer::timeout,this,[this]{
        if(m_tickState)
            m_tickState=false;
        else
            m_tickState=true;
    });
}

void RoundLamp::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    int width=this->width();
    int height=this->height();
    int side=qMin(width,height);

    QPainter p(this);
    p.translate(width/2,height/2);
    p.scale(side/200.0,side/200.0);
    p.setPen(Qt::NoPen);

    if(m_canTick&&(!m_tickTimer.isActive()))
        m_tickTimer.start(m_tickTime);
    else if(!m_canTick&&m_tickTimer.isActive())
        m_tickTimer.stop();

    upFrameOut(&p,99);
    upFrameIn(&p,90);
    upLampColor(&p,80);
    upText(&p);
}

void RoundLamp::setOnColor(QColor onColor)
{
    m_onColor = onColor;
    update();
}

         以上是两种用QT实现自定义指示灯控件的形式化方法,可以根据具体需求选择适合的方式。这只是一个简单的示例,你可以根据你的需求对这个自定义控件进行扩展和修改。

五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中使用此控件:

#include "mainwindow.h"
#include "imagelamp.h"
#include "roundlamp.h"
#include <QGridLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ImageLamp *pImageLamp = new ImageLamp(QPixmap(":/res/lampON.png"),QPixmap(":/res/lampOFF.png"),this);
    pImageLamp->setState(true);//点亮后才能闪烁
    pImageLamp->setCanTick(true);

    RoundLamp *pRoundLamp = new RoundLamp(this);
    pRoundLamp->setState(true);
    pRoundLamp->setCanTick(true);
//    pRoundLamp->setOnColor(QColor("red"));

    QWidget *widget = new QWidget(this);
    QGridLayout *layout = new QGridLayout(widget);
    layout->addWidget(pImageLamp);
    layout->addWidget(pRoundLamp);
    setCentralWidget(widget);

    resize(400, 400);
}

MainWindow::~MainWindow()
{
}

        在示例中,通过setStatus函数来设置指示灯的状态。        

        总结一下QT自定义指示灯是一种用于显示系统状态或操作提示的图标或灯光。它可以根据需要进行自定义,可以用不同的颜色、形状和动画效果来表示不同的状态或提示信息。QT自定义指示灯可以在QT界面程序中使用,通过设置其状态或属性来实现不同的显示效果。总的来说,QT自定义指示灯可以为用户提供直观的视觉反馈,帮助用户理解系统当前的状态或操作需求,提升用户体验。

        谢谢您的关注和阅读。如果您还有其他问题或需要进一步的帮助,请随时联系我。祝您一切顺利!

六、源代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值