最近因为在玩iOS手机,突然觉得人家的开关就是很好看,于是乎自己花了点时间写了一下,下面是效果图,代码中没有使用定时器,而是直接用的属性动画,并且支持横向和竖向动态缩放。
实现代码如下:
Switch.h
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
enum class AnimationType
{
NoAnimation, //没有动画
PropertyAnimation, //属性动画
};
class QPropertyAnimation;
class Switch : public QWidget
{
Q_OBJECT
public:
Switch(QWidget *parent = nullptr);
~Switch();
protected:
virtual void paintEvent(QPaintEvent *e) override;
virtual void resizeEvent(QResizeEvent *e) override;
virtual void mousePressEvent(QMouseEvent *e) override;
private slots:
void OnValueChanged(QVariant);
private:
void CalcSliderPos();
void PaintLeftArea(QPainter&,int);
void PaintRightArea(QPainter&,int);
void PaintSliderArea(QPainter&,int);
private:
bool m_IsOpen; //当前状态
int m_SliderPos; //滑块当前位置
QColor m_CloseBgColor; //关闭后背景颜色
QColor m_OpenBgColor; //打开后背景颜色
QColor m_SliderBgColor; //滑块背景颜色
AnimationType m_AnimationType; //动画类型
QPropertyAnimation* m_PropertyAnimation;
};
#endif // WIDGET_H
Swtich.cpp
#include "Switch.h"
#include
#include
#include
Switch:: Switch(QWidget *parent)
: QWidget(parent)
, m_IsOpen(false)
, m_SliderPos(0)
, m_CloseBgColor(Qt::gray)
, m_OpenBgColor(Qt::green)
, m_SliderBgColor(Qt::white)
, m_AnimationType(AnimationType::PropertyAnimation)
, m_PropertyAnimation(Q_NULLPTR)
{
switch(m_AnimationType)
{
case AnimationType::NoAnimation:
break;
case AnimationType::PropertyAnimation:
m_PropertyAnimation = new QPropertyAnimation(this,"");
connect(m_PropertyAnimation,&QPropertyAnimation::valueChanged,this,&Switch::OnValueChanged);
break;
default:
break;
}
}
Switch::~ Switch()
{}
void Switch::CalcSliderPos()
{
int size=qMin(width(),height());
if(m_IsOpen){
if(width()height()-size;
}
else{
m_SliderPos = width()-size;
}
}
else{
m_SliderPos = 0;
}
}
void Switch::resizeEvent(QResizeEvent *e)
{
CalcSliderPos();
QWidget::resizeEvent(e);
}
void Switch::mousePressEvent(QMouseEvent *e)
{
if(Qt::LeftButton==e->button()){
m_IsOpen=!m_IsOpen;
switch(m_AnimationType)
{
case AnimationType::NoAnimation:
CalcSliderPos();
update();
break;
case AnimationType::PropertyAnimation:
if(Q_NULLPTR==m_PropertyAnimation){
CalcSliderPos();
update();
}
else{
m_PropertyAnimation->stop();
if(m_IsOpen){
m_PropertyAnimation->setStartValue(0);
m_PropertyAnimation->setEndValue(qAbs(width()-height()));
}
else{
m_PropertyAnimation->setStartValue (qAbs(width()-height()));
m_PropertyAnimation->setEndValue(0);
}
m_PropertyAnimation->setDuration(200);
m_PropertyAnimation->start();
}
break;
default:
break;
}
}
}
void Switch::OnValueChanged(QVariant value)
{
m_SliderPos=value.toInt();
update();
}
void Switch::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
//设置反走样
painter.setRenderHint(QPainter::Antialiasing, true);
int size=qMin(width(),height());
PaintLeftArea(painter,size);
PaintRightArea(painter,size);
PaintSliderArea(painter,size);
QWidget::paintEvent(e);
}
void Switch::PaintLeftArea(QPainter& painter,int size)
{
painter.save();
//计算左边外框线
QPainterPath painterPath;
painterPath.addEllipse(0,0,size,size);
if(width()
这里的私有变量可以通过共有接口设置以供外部调用设置颜色等。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)