指示灯的应用场景很广泛,随着科技的进步和创新,指示灯的应用也在不断扩展和改进。指示灯在用户界面中常用于表示状态、警告或提示信息。在Qt中,可以通过自定义继承QWidget的类来实现自定义指示灯控件。本文将介绍实现两种形式。1、使用QPixmap绘制指示灯;2、在paintEvent中使用QPainter来绘制。
一、简述
QT自定义指示灯控件。要实现自定义指示灯控件,首先需要创建一个自定义的QWidget类,并在这个类中重写绘图事件(paintEvent)。在paintEvent中,可以使用QT提供的绘图函数来绘制指示灯的外观。可以根据不同的状态设置不同的颜色、形状或图标等。
二、 设计思路
- 创建一个QWidget子类Lamp作为指示灯的基类。
- 在Lamp类中,定义指示灯的常规属性。
- 创建一个Lamp的子类ImageLamp,重写paintEvent()函数,使用QPixmap绘制指示灯。(以图片的形式绘制)
- 创建一个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自定义指示灯可以为用户提供直观的视觉反馈,帮助用户理解系统当前的状态或操作需求,提升用户体验。
谢谢您的关注和阅读。如果您还有其他问题或需要进一步的帮助,请随时联系我。祝您一切顺利!