最近因为在玩iOS手机,突然觉得人家的开关就是很好看,于是乎自己花了点时间写了一下,下面是效果图,代码中没有使用定时器,而是直接用的属性动画,并且支持横向和竖向动态缩放。
文章图片
实现代码如下:
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开关实现】这里的私有变量可以通过共有接口设置以供外部调用设置颜色等。
推荐阅读
- Python|为什么学完Python后的薪资这么高()
- Phthon|Python datacompy 找出两个DataFrames不同的地方
- 数据可视化|Python绘制疫情地图 超简单!
- Python|使用python对全球最新疫情情况进行可视化地图绘制!
- java|如何写出让同事无法维护的代码()
- 【Python】|Python 代码规范
- java|云原生爱好者周刊(Grafana Loki 免费电子书)
- 大数据|11 个可以部署在 Linux 服务器上的开源论坛软件 | Linux 中国
- 嵌入式|构建嵌入式linux系统_用于构建嵌入式Linux系统的4种工具