
CustomCheckBox.h
#ifndef CUSTOMCHECKBOX_H
#define CUSTOMCHECKBOX_H
#include <QCheckBox>
#include <QLabel>
#include <QStyle>
#include <QLabel>
#include <QMouseEvent>
#include <QApplication>
#include <QPropertyAnimation>
#include <QGraphicsDropShadowEffect>
class CustomCheckBox : public QCheckBox
{
Q_OBJECT
public:
explicit CustomCheckBox(QWidget *parent = nullptr);
protected:
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
private:
// checked 为 false 时 indicator 在最左边,为 true 时 indicator 在最右边
QLabel *indicator;
};
#endif // CUSTOMCHECKBOX_H
CustomCheckBox.cpp
#include "CustomCheckBox.h"
CustomCheckBox::CustomCheckBox(QWidget *parent)
: QCheckBox{parent}
{
indicator = new QLabel(this);
qDebug()<<this->size();
// 设置样式
this->setMinimumHeight(20);
this->setContentsMargins(2, 2, 2, 2);
this->setAttribute(Qt::WA_StyledBackground, true);
this->setProperty("class", "AnimatedCheckBox");
indicator->setProperty("class", "AnimatedCheckBoxIndicator");
QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this);//添加阴影
effect->setBlurRadius(10);//模糊半径
effect->setOffset(0, 1);//偏移
indicator->setGraphicsEffect(effect);
// AnimatedCheckBox 的选中状态变化时,动态修改 indicator 的位置
QPropertyAnimation *animation = new QPropertyAnimation(indicator, "pos", this);
connect(this, &QCheckBox::toggled, [=] {
int b = this->contentsMargins().left();
int x = this->isChecked() ? this->width() - indicator->width() - b : b;
int y = b;
// indicator->move(x,y);
animation->stop();
animation->setDuration(200);
animation->setEndValue(QPoint(x, y));
animation->setEasingCurve(QEasingCurve::InOutCubic);
animation->start();
this->style()->polish(this); // checked 属性变化了,更新样式
});
}
void CustomCheckBox::mousePressEvent(QMouseEvent *event)
{
event->accept();
setChecked(!isChecked());
}
void CustomCheckBox::paintEvent(QPaintEvent *)
{
//清除 QCheckBox 的默认样式
}
void CustomCheckBox::resizeEvent(QResizeEvent *)
{
qDebug()<<this->size();
int b = this->contentsMargins().left();
int x = this->isChecked() ? this->width() - indicator->width() - b : b;
int y = b;
int w = height() - b - b;
int h = w;
indicator->setGeometry(x, y, w, h);
// 设置 AnimatedCheckBox 的最小宽度,避免太窄的时候效果不好
this->setMinimumWidth(height() * 2);
// 更新 check box 和 indicator 的圆角大小
this->setStyleSheet(QString(".AnimatedCheckBox { border-radius: %1px } .AnimatedCheckBoxIndicator { border-radius: %2px }")
.arg(this->height() / 2)
.arg(indicator->height() / 2));
}
样式表
.AnimatedCheckBox[checked=true ] {
background: green;
}
.AnimatedCheckBox[checked=false] {
background: gray;
}
.AnimatedCheckBoxIndicator {
background: white
}
使用:
将QCheckBox提升为该类
new 出该类对象