重新实现paintEvent()函数。
效果如下:
效果为蓝色区域,背景是vs接面,代码直接复制可用,留给有需要的人。
cpp
#ifndef CircleWidget_h__
#define CircleWidget_h__
#include <QWidget>
class CCircleWidget : public QWidget
{
Q_OBJECT
public:
explicit CCircleWidget(QWidget* parent = 0); // explicit 避免歧义
CCircleWidget(const QString& strImagePath, int nRadius, QWidget* parent = 0);
public:
void SetNormalOutLineColor(QColor color);
void SetHoverOutLineColor(QColor color);
void SetPressedOutLineColor(QColor color);
void SetOutLineWidth(int nWidth);
void SetImagePath(const QString& strImagePath);
void SetHovered(bool bHovered);
void SetPressed(bool bPressed);
protected: // override
void Init();
void paintEvent(QPaintEvent*) override; // 绘图事件,调用update()时触发
void mousePressEvent(QMouseEvent* e) override; // 鼠标按下事件
void mouseReleaseEvent(QMouseEvent* e) override; // 鼠标释放事件
void enterEvent(QEvent*) override; // 鼠标进入事件
void leaveEvent(QEvent*) override; // 鼠标离开事件
signals:
void SigClicked(); // 点击信号
private:
QString m_strImagePath; // 图片路径
QColor m_normalColor;
QColor m_hoverColor;
QColor m_pressedColor;
int m_nWidth;
int m_nRadius; // 圆形半径
bool m_bPressed; // 左键单击控制
bool m_bHovered; // 鼠标悬停控制
};
#endif // CircleWidget_h__
cpp
#include "CircleWidget.h"
#include <QPainter>
#include <QMouseEvent>
CCircleWidget::CCircleWidget(QWidget* parent)
: QWidget(parent)
, m_strImagePath(":/dotnetIcon.png")
, m_normalColor("#58a3ef")
, m_hoverColor("#6eb8f5")
, m_pressedColor("#417cac")
, m_nWidth(4)
, m_nRadius(46)
, m_bPressed(false)
, m_bHovered(false)
{
Init();
}
CCircleWidget::CCircleWidget(const QString& strImagePath, int nRadius, QWidget* parent)
: QWidget(parent)
, m_strImagePath(strImagePath)
, m_normalColor("#58a3ef")
, m_hoverColor("#6eb8f5")
, m_pressedColor("#417cac")
, m_nWidth(4)
, m_nRadius(nRadius)
, m_bPressed(false)
, m_bHovered(false)
{
Init();
}
void CCircleWidget::SetNormalOutLineColor(QColor color)
{
m_normalColor = color;
}
void CCircleWidget::SetHoverOutLineColor(QColor color)
{
m_hoverColor = color;
}
void CCircleWidget::SetPressedOutLineColor(QColor color)
{
m_pressedColor = color;
}
void CCircleWidget::SetOutLineWidth(int nWidth)
{
m_nWidth = nWidth;
}
void CCircleWidget::SetImagePath(const QString& strImagePath)
{
m_strImagePath = strImagePath;
}
void CCircleWidget::SetHovered(bool bHovered)
{
m_bHovered = bHovered;
update();
}
void CCircleWidget::SetPressed(bool bPressed)
{
m_bPressed = bPressed;
update();
}
void CCircleWidget::Init()
{
// 无边框
setWindowFlags(Qt::FramelessWindowHint);
// 窗口背景透明
setAttribute(Qt::WA_TranslucentBackground, true);
}
void CCircleWidget::paintEvent(QPaintEvent*)
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QPen pen;
pen.setWidth(m_nWidth);
if (m_bPressed)
{
pen.setColor("#417cac"); // 按下时的边框颜色
}
else if (m_bHovered)
{
pen.setColor("#6eb8f5"); // 悬停时的边框颜色
}
else
{
pen.setColor("#58a3ef"); // 正常状态的边框颜色
}
p.setPen(pen);
p.setBrush(Qt::NoBrush);
// 设置圆心为圆的半径,以确保圆形完整显示
//QPoint center(m_nRadius + m_nWidth / 2, m_nRadius + m_nWidth / 2);
QPoint center(rect().center());
// 绘制背景圆形
p.drawEllipse(center, m_nRadius, m_nRadius);
// 绘制图片
QPixmap pixmap(m_strImagePath);
QRect imageRect(0, 0, 2 * m_nRadius, 2 * m_nRadius); // 计算图片绘制区域
QPainterPath clipPath;
clipPath.addEllipse(center, m_nRadius, m_nRadius);
p.setClipPath(clipPath);
p.drawPixmap(center.x() - m_nRadius, center.y() - m_nRadius, imageRect.width(), imageRect.height(), pixmap);
}
void CCircleWidget::mousePressEvent(QMouseEvent* e)
{
m_bPressed = true;
update();
}
void CCircleWidget::mouseReleaseEvent(QMouseEvent* e)
{
m_bPressed = false;
update();
}
void CCircleWidget::enterEvent(QEvent*)
{
m_bHovered = true;
update();
}
void CCircleWidget::leaveEvent(QEvent*)
{
m_bHovered = false;
update();
}