在日常需求中,需要对功能增加一个开关,因此做了简单封装。结果能正常使用。自定义信号接收!
实现
QWidget* switchBtn = new CCendSwitchWidget(btn_value);
connect(switchBtn, SIGNAL(clicked(bool,QString)), this, SLOT(clickedSlot(bool, QString)));
头文件
#ifndef C_CEND_SWITCH_WIDGET_H
#define C_CEND_SWITCH_WIDGET_H
#include <QWidget>
#include <QPainter>
#include <QEvent>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QVariantAnimation>
#include <QMap>
#include <QGuiApplication>
#include <string>
using std::string;
class CCendSwitchWidget : public QWidget
{
Q_OBJECT
public:
CCendSwitchWidget(QString,QWidget* parent = 0);
QSize sizeHint() const override;
bool isOpened() const;
signals:
void clicked(bool,QString);
private:
void setButtonPos(float where);
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
private:
bool opened;
bool hover;
float atWhere; /* [0, 1] */
QPoint pressPt;
QString m_pDataType;
};
#endif //C_CEND_SWITCH_WIDGET_H
cpp
#include "CCendSwitchWidget.h"
CCendSwitchWidget::CCendSwitchWidget(QString type,QWidget* parent) :
QWidget(parent)
{
m_pDataType = type;
opened = false;
hover = false;
atWhere = 0;
}
void CCendSwitchWidget::setButtonPos(float where)
{
atWhere = where;
update();
}
bool CCendSwitchWidget::isOpened() const
{
return opened;
}
void CCendSwitchWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
qreal rad = height() * 0.5; /* 圆半径 */
int xleft = rad;
int xright = width() - rad;
int xpos = xleft + (xright - xleft) * atWhere;
painter.setPen(Qt::NoPen);
painter.setBrush((xpos == xright) ? QColor(0, 170, 255) : QColor(173, 173, 173));
painter.drawRoundedRect(0, 0, width(), height(), rad, rad);
if (hover) /* 鼠标悬停稍微提亮一点 */
{
painter.setBrush(QColor(255, 255, 255, 63));
painter.drawRoundedRect(0, 0, width(), height(), rad, rad);
}
painter.setPen(QColor(213, 213, 213));
painter.setBrush(QColor(243, 243, 243));
painter.drawEllipse(QPointF(xpos, rad), rad - 1, rad - 1);
}
void CCendSwitchWidget::mousePressEvent(QMouseEvent *event)
{
pressPt = event->pos();
}
void CCendSwitchWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (pressPt == event->pos())
{
opened = !opened;
emit clicked(opened, m_pDataType);
QVariantAnimation* ani = new QVariantAnimation(this);
ani->setStartValue(0.0f);
ani->setEndValue(1.0f);
ani->setDuration(200);
ani->setDirection(opened ? QVariantAnimation::Forward : QVariantAnimation::Backward);
connect(ani, &QVariantAnimation::valueChanged, this,
[this](const QVariant& value) { setButtonPos(value.toFloat()); });
ani->start(QAbstractAnimation::DeleteWhenStopped);
}
}
void CCendSwitchWidget::enterEvent(QEvent *event)
{
hover = true;
update();
}
void CCendSwitchWidget::leaveEvent(QEvent *event)
{
hover = false;
update();
}
QSize CCendSwitchWidget::sizeHint() const
{
return QSize(21, 10);
}
最准效果
参考
https://www.cnblogs.com/mengxiangdu/p/16926176.html