按钮 重绘 【Qt UI界面美化】【paintEvent】

//.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 可以切换实现方法

效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值