Qt自绘控件|Qt仿iOS的Switch开关实现

最近因为在玩iOS手机,突然觉得人家的开关就是很好看,于是乎自己花了点时间写了一下,下面是效果图,代码中没有使用定时器,而是直接用的属性动画,并且支持横向和竖向动态缩放。
Qt自绘控件|Qt仿iOS的Switch开关实现
文章图片

实现代码如下:
Switch.h

#ifndef WIDGET_H #define WIDGET_H#include #include enum class AnimationType { NoAnimation, //没有动画 PropertyAnimation, //属性动画 }; class QPropertyAnimation; class Switch : public QWidget { Q_OBJECTpublic: 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()

【Qt自绘控件|Qt仿iOS的Switch开关实现】这里的私有变量可以通过共有接口设置以供外部调用设置颜色等。

    推荐阅读