目录
一.初始化对象
二.捕获并处理特定的事件
三.自定义绘制方法
四.绘制外部边框
五.绘制内部边框
六.绘制按钮的背景色
七.绘制覆盖层(高光效果)
八.效果
九.代码
1.h
2.cpp
一.初始化对象
1.设置文本、颜色、边框和背景色等默认值。
2.安装事件过滤器以捕获鼠标事件。
3.创建定时器 timerAlarm
用于处理报警状态,并连接到槽函数 alarm()
。
二.捕获并处理特定的事件
1.当检测到鼠标按下事件时,如果点击在按钮范围内,则记录当前点并设置 pressed = true
。
2.如果正在拖动按钮且允许移动,则更新按钮的位置。
3.当鼠标释放时,重置 pressed
状态并发出点击信号 (clicked()
)。
三.自定义绘制方法
1.根据 showRect
的值决定绘制矩形或其他图形元素(如边框、背景、文字等)。
2.使用抗锯齿技术提高绘制质量。
四.绘制外部边框
使用线性渐变填充颜色绘制圆形边框,分别为外层和内层
五.绘制内部边框
六.绘制按钮的背景色
绘制一个圆形作为背景,使用设置好的背景颜色填充
七.绘制覆盖层(高光效果)
如果启用遮罩层,则根据指定半径绘制小圆圈和大圆圈形成高光效果,并应用渐变色填充。
八.效果
九.代码
1.h
#ifndef LIGHTBUTTON_H
#define LIGHTBUTTON_H
#include <QWidget>#ifdef quc
class Q_DECL_EXPORT LightButton : public QWidget
#else
class LightButton : public QWidget
#endif{Q_OBJECTQ_PROPERTY(QString text READ getText WRITE setText)Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)Q_PROPERTY(QColor alarmColor READ getAlarmColor WRITE setAlarmColor)Q_PROPERTY(QColor normalColor READ getNormalColor WRITE setNormalColor)Q_PROPERTY(QColor borderOutColorStart READ getBorderOutColorStart WRITE setBorderOutColorStart)Q_PROPERTY(QColor borderOutColorEnd READ getBorderOutColorEnd WRITE setBorderOutColorEnd)Q_PROPERTY(QColor borderInColorStart READ getBorderInColorStart WRITE setBorderInColorStart)Q_PROPERTY(QColor borderInColorEnd READ getBorderInColorEnd WRITE setBorderInColorEnd)Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)Q_PROPERTY(bool canMove READ getCanMove WRITE setCanMove)Q_PROPERTY(bool showRect READ getShowRect WRITE setShowRect)Q_PROPERTY(bool showOverlay READ getShowOverlay WRITE setShowOverlay)Q_PROPERTY(QColor overlayColor READ getOverlayColor WRITE setOverlayColor)public:explicit LightButton(QWidget *parent = 0);protected:bool eventFilter(QObject *watched, QEvent *event);void paintEvent(QPaintEvent *);void drawBorderOut(QPainter *painter);void drawBorderIn(QPainter *painter);void drawBg(QPainter *painter);void drawText(QPainter *painter);void drawOverlay(QPainter *painter);private:QString text; //文本QColor textColor; //文字颜色QColor alarmColor; //报警颜色QColor normalColor; //正常颜色QColor borderOutColorStart; //外边框渐变开始颜色QColor borderOutColorEnd; //外边框渐变结束颜色QColor borderInColorStart; //里边框渐变开始颜色QColor borderInColorEnd; //里边框渐变结束颜色QColor bgColor; //背景颜色bool showRect; //显示成矩形bool canMove; //是否能够移动bool showOverlay; //是否显示遮罩层QColor overlayColor; //遮罩层颜色bool pressed; //鼠标是否按下QPoint lastPoint; //鼠标最后按下坐标bool isAlarm; //是否报警QTimer *timerAlarm; //定时器切换颜色public://默认尺寸和最小尺寸QSize sizeHint() const;QSize minimumSizeHint() const;//获取和设置文本QString getText() const;void setText(const QString &text);//获取和设置文本颜色QColor getTextColor() const;void setTextColor(const QColor &textColor);//获取和设置报警颜色QColor getAlarmColor() const;void setAlarmColor(const QColor &alarmColor);//获取和设置正常颜色QColor getNormalColor() const;void setNormalColor(const QColor &normalColor);//获取和设置外边框渐变颜色QColor getBorderOutColorStart() const;void setBorderOutColorStart(const QColor &borderOutColorStart);QColor getBorderOutColorEnd() const;void setBorderOutColorEnd(const QColor &borderOutColorEnd);//获取和设置里边框渐变颜色QColor getBorderInColorStart() const;void setBorderInColorStart(const QColor &borderInColorStart);QColor getBorderInColorEnd() const;void setBorderInColorEnd(const QColor &borderInColorEnd);//获取和设置背景色QColor getBgColor() const;void setBgColor(const QColor &bgColor);//获取和设置是否可移动bool getCanMove() const;void setCanMove(bool canMove);//获取和设置是否显示矩形bool getShowRect() const;void setShowRect(bool showRect);//获取和设置是否显示遮罩层bool getShowOverlay() const;void setShowOverlay(bool showOverlay);//获取和设置遮罩层颜色QColor getOverlayColor() const;void setOverlayColor(const QColor &overlayColor);public Q_SLOTS://设置为绿色void setGreen();//设置为红色void setRed();//设置为黄色void setYellow();//设置为黑色void setBlack();//设置为灰色void setGray();//设置为蓝色void setBlue();//设置为淡蓝色void setLightBlue();//设置为淡红色void setLightRed();//设置为淡绿色void setLightGreen();//设置报警闪烁void startAlarm();void stopAlarm();void alarm();Q_SIGNALS://单击信号void clicked();
};#endif // LIGHTBUTTON_H
2.cpp
#pragma execution_character_set("utf-8")#include "lightbutton.h"
#include "qpainter.h"
#include "qpainterpath.h"
#include "qevent.h"
#include "qtimer.h"LightButton::LightButton(QWidget *parent) : QWidget(parent)
{text = "";textColor = QColor(255, 255, 255);alarmColor = QColor(255, 107, 107);normalColor = QColor(10, 10, 10);borderOutColorStart = QColor(255, 255, 255);borderOutColorEnd = QColor(166, 166, 166);borderInColorStart = QColor(166, 166, 166);borderInColorEnd = QColor(255, 255, 255);bgColor = QColor(100, 184, 255);showRect = false;showOverlay = true;overlayColor = QColor(255, 255, 255);canMove = false;pressed = false;this->installEventFilter(this);isAlarm = false;timerAlarm = new QTimer(this);connect(timerAlarm, SIGNAL(timeout()), this, SLOT(alarm()));timerAlarm->setInterval(500);
}bool LightButton::eventFilter(QObject *watched, QEvent *event)
{int type = event->type();QMouseEvent *mouseEvent = (QMouseEvent *)event;if (type == QEvent::MouseButtonPress) {if (this->rect().contains(mouseEvent->pos()) && (mouseEvent->button() == Qt::LeftButton)) {lastPoint = mouseEvent->pos();pressed = true;}} else if (type == QEvent::MouseMove && pressed) {if (canMove) {int dx = mouseEvent->pos().x() - lastPoint.x();int dy = mouseEvent->pos().y() - lastPoint.y();this->move(this->x() + dx, this->y() + dy);}} else if (type == QEvent::MouseButtonRelease && pressed) {pressed = false;Q_EMIT clicked();}return QWidget::eventFilter(watched, event);
}void LightButton::paintEvent(QPaintEvent *)
{int width = this->width();int height = this->height();int side = qMin(width, height);//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);if (showRect) {//绘制矩形区域painter.setPen(Qt::NoPen);painter.setBrush(bgColor);painter.drawRoundedRect(this->rect(), 5, 5);//绘制文字if (!text.isEmpty()) {QFont font;font.setPixelSize(side - 20);painter.setFont(font);painter.setPen(textColor);painter.drawText(this->rect(), Qt::AlignCenter, text);}} else {painter.translate(width / 2, height / 2);painter.scale(side / 200.0, side / 200.0);//绘制外边框drawBorderOut(&painter);//绘制内边框drawBorderIn(&painter);//绘制内部指示颜色drawBg(&painter);//绘制居中文字drawText(&painter);//绘制遮罩层drawOverlay(&painter);}
}void LightButton::drawBorderOut(QPainter *painter)
{int radius = 99;painter->save();painter->setPen(Qt::NoPen);QLinearGradient borderGradient(0, -radius, 0, radius);borderGradient.setColorAt(0, borderOutColorStart);borderGradient.setColorAt(1, borderOutColorEnd);painter->setBrush(borderGradient);painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);painter->restore();
}void LightButton::drawBorderIn(QPainter *painter)
{int radius = 90;painter->save();painter->setPen(Qt::NoPen);QLinearGradient borderGradient(0, -radius, 0, radius);borderGradient.setColorAt(0, borderInColorStart);borderGradient.setColorAt(1, borderInColorEnd);painter->setBrush(borderGradient);painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);painter->restore();
}void LightButton::drawBg(QPainter *painter)
{int radius = 80;painter->save();painter->setPen(Qt::NoPen);painter->setBrush(bgColor);painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);painter->restore();
}void LightButton::drawText(QPainter *painter)
{if (text.isEmpty()) {return;}int radius = 100;painter->save();QFont font;font.setPixelSize(85);painter->setFont(font);painter->setPen(textColor);QRect rect(-radius, -radius, radius * 2, radius * 2);painter->drawText(rect, Qt::AlignCenter, text);painter->restore();
}void LightButton::drawOverlay(QPainter *painter)
{if (!showOverlay) {return;}int radius = 80;painter->save();painter->setPen(Qt::NoPen);QPainterPath smallCircle;QPainterPath bigCircle;radius -= 1;smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);radius *= 2;bigCircle.addEllipse(-radius, -radius + 140, radius * 2, radius * 2);//高光的形状为小圆扣掉大圆的部分QPainterPath highlight = smallCircle - bigCircle;QLinearGradient linearGradient(0, -radius / 2, 0, 0);overlayColor.setAlpha(100);linearGradient.setColorAt(0.0, overlayColor);overlayColor.setAlpha(30);linearGradient.setColorAt(1.0, overlayColor);painter->setBrush(linearGradient);painter->rotate(-20);painter->drawPath(highlight);painter->restore();
}QSize LightButton::sizeHint() const
{return QSize(100, 100);
}QSize LightButton::minimumSizeHint() const
{return QSize(10, 10);
}QString LightButton::getText() const
{return this->text;
}void LightButton::setText(const QString &text)
{if (this->text != text) {this->text = text;this->update();}
}QColor LightButton::getTextColor() const
{return this->textColor;
}void LightButton::setTextColor(const QColor &textColor)
{if (this->textColor != textColor) {this->textColor = textColor;this->update();}
}QColor LightButton::getAlarmColor() const
{return this->alarmColor;
}void LightButton::setAlarmColor(const QColor &alarmColor)
{if (this->alarmColor != alarmColor) {this->alarmColor = alarmColor;this->update();}
}QColor LightButton::getNormalColor() const
{return this->normalColor;
}void LightButton::setNormalColor(const QColor &normalColor)
{if (this->normalColor != normalColor) {this->normalColor = normalColor;this->update();}
}QColor LightButton::getBorderOutColorStart() const
{return this->borderOutColorStart;
}void LightButton::setBorderOutColorStart(const QColor &borderOutColorStart)
{if (this->borderOutColorStart != borderOutColorStart) {this->borderOutColorStart = borderOutColorStart;this->update();}
}QColor LightButton::getBorderOutColorEnd() const
{return this->borderOutColorEnd;
}void LightButton::setBorderOutColorEnd(const QColor &borderOutColorEnd)
{if (this->borderOutColorEnd != borderOutColorEnd) {this->borderOutColorEnd = borderOutColorEnd;this->update();}
}QColor LightButton::getBorderInColorStart() const
{return this->borderInColorStart;
}void LightButton::setBorderInColorStart(const QColor &borderInColorStart)
{if (this->borderInColorStart != borderInColorStart) {this->borderInColorStart = borderInColorStart;this->update();}
}QColor LightButton::getBorderInColorEnd() const
{return this->borderInColorEnd;
}void LightButton::setBorderInColorEnd(const QColor &borderInColorEnd)
{if (this->borderInColorEnd != borderInColorEnd) {this->borderInColorEnd = borderInColorEnd;this->update();}
}QColor LightButton::getBgColor() const
{return this->bgColor;
}void LightButton::setBgColor(const QColor &bgColor)
{if (this->bgColor != bgColor) {this->bgColor = bgColor;this->update();}
}bool LightButton::getCanMove() const
{return this->canMove;
}void LightButton::setCanMove(bool canMove)
{if (this->canMove != canMove) {this->canMove = canMove;this->update();}
}bool LightButton::getShowRect() const
{return this->showRect;
}void LightButton::setShowRect(bool showRect)
{if (this->showRect != showRect) {this->showRect = showRect;this->update();}
}bool LightButton::getShowOverlay() const
{return this->showOverlay;
}void LightButton::setShowOverlay(bool showOverlay)
{if (this->showOverlay != showOverlay) {this->showOverlay = showOverlay;this->update();}
}QColor LightButton::getOverlayColor() const
{return this->overlayColor;
}void LightButton::setOverlayColor(const QColor &overlayColor)
{if (this->overlayColor != overlayColor) {this->overlayColor = overlayColor;this->update();}
}void LightButton::setGreen()
{textColor = QColor(255, 255, 255);setBgColor(QColor(0, 166, 0));
}void LightButton::setRed()
{textColor = QColor(255, 255, 255);setBgColor(QColor(255, 0, 0));
}void LightButton::setYellow()
{textColor = QColor(25, 50, 7);setBgColor(QColor(238, 238, 0));
}void LightButton::setBlack()
{textColor = QColor(255, 255, 255);setBgColor(QColor(10, 10, 10));
}void LightButton::setGray()
{textColor = QColor(255, 255, 255);setBgColor(QColor(129, 129, 129));
}void LightButton::setBlue()
{textColor = QColor(255, 255, 255);setBgColor(QColor(0, 0, 166));
}void LightButton::setLightBlue()
{textColor = QColor(255, 255, 255);setBgColor(QColor(100, 184, 255));
}void LightButton::setLightRed()
{textColor = QColor(255, 255, 255);setBgColor(QColor(255, 107, 107));
}void LightButton::setLightGreen()
{textColor = QColor(255, 255, 255);setBgColor(QColor(24, 189, 155));
}void LightButton::startAlarm()
{if (!timerAlarm->isActive()) {timerAlarm->start();}
}void LightButton::stopAlarm()
{if (timerAlarm->isActive()) {timerAlarm->stop();}
}void LightButton::alarm()
{if (isAlarm) {textColor = QColor(255, 255, 255);bgColor = normalColor;} else {textColor = QColor(255, 255, 255);bgColor = alarmColor;}this->update();isAlarm = !isAlarm;
}