//.h头文件
#pragma once
#include <QToolButton>
#include <QObject>
struct SwitchBtnPrivate;
class SwitchBtn :public QToolButton
{
Q_OBJECT
public:
void setOpen(bool bOpen);
bool isOpen();
signals:
public slots:
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *e);
public:
explicit SwitchBtn(QWidget *parent = Q_NULLPTR);
~SwitchBtn();
private:
SwitchBtnPrivate * m_pData;
};
//.cpp 源文件
#include "SwitchBtn.h"
#include <QPainter>
#include <iostream>
#include <QPropertyAnimation>
//#define APPROACHES_1 //定义实现方法
struct SwitchBtnPrivate
{
public:
void init()
{
bOpen = true;
}
bool bOpen;
};
//计算圆角,我测试了小到37*18,大到500*200,圆角计算都是没问题的,可以算自适应了。
qreal calculateRadius(int nHeight)
{
return ((qreal)nHeight) / 2 * 3 / 4 * 6 / 5 * 8 / 7;
}
void SwitchBtn::setOpen(bool bOpen)
{
this->m_pData->bOpen = bOpen;
}
bool SwitchBtn::isOpen()
{
return this->m_pData->bOpen;
}
void SwitchBtn::paintEvent(QPaintEvent *)
{
int nPenWidth = 2;
QPainter painter(this);
// 设置抗锯齿和平滑像素变换
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
// 计算绘制区域,直接使用 QRectF
QRectF rect(1, 1, rect().width() - 2, rect().height() - 2);
qreal radius = calculateRadius(rect.height());
QPen pen;
pen.setWidth(nPenWidth);
painter.setPen(pen);
#ifdef APPROACHES_1
//画圆
QRectF circleRect;
painter.drawRoundedRect(rect, radius, radius);
if (isOpen())
{
circleRect = QRectF(rect.right() - rect.height(), rect.top(), rect.height(), rect.height());
painter.setBrush(QColor(76, 217, 100));
}
else
{
circleRect = QRectF(rect.left(), rect.top(), rect.height(), rect.height());
painter.setBrush(QColor(255, 59, 48));
}
#else APPROACHES_2
// 使用 QPainterPath 绘制圆角矩形
QPainterPath backimg;
backimg.addRoundedRect(rect, radius, radius);
// 使用 fillPath 函数填充矩形,无需设置画刷
painter.fillPath(backimg, this->isOpen() ? QColor(76, 217, 100) : QColor(255, 59, 48));
// 计算圆大小位置和画刷颜色
QRectF circleRect;
if (isOpen())
{
circleRect = QRectF(rect.right() - rect.height() + nPenWidth, rect.top() + nPenWidth, rect.height() - nPenWidth * 2, rect.height() - nPenWidth * 2);
}
else
{
circleRect = QRectF(rect.left()+ nPenWidth, rect.top()+ nPenWidth, rect.height()- nPenWidth * 2, rect.height()- nPenWidth * 2);
}
painter.setPen(QColor(255, 255, 255));
painter.setBrush(QColor(255, 255, 255));
#endif
painter.drawEllipse(circleRect);
}
void SwitchBtn::mousePressEvent(QMouseEvent * e)
{
setOpen(!isOpen());
update();
}
SwitchBtn::SwitchBtn(QWidget * parent)
: QToolButton(parent),m_pData(new SwitchBtnPrivate)
{
m_pData->init();
}
SwitchBtn::~SwitchBtn()
{
delete m_pData;
}
原文链接:https ://blog.csdn.net/u013728640/article/details/133176499
现效果一共两种,打开/关闭#define APPROACHES_1 可以切换实现方法
效果: