1 #include "qswitchcontrol.h"
2
3 #include <QPushButton>
4 #include <QPropertyAnimation>
5 #include <QStyleOption>
6 #include <QPainter>
7
8 static const QSize FrameSize = QSize(68, 30);
9 static const QSize SwitchSize = QSize (26, 26);
10 static const int SwitchOffset = (FrameSize.height() - SwitchSize.height()) / 2;
11
12 static const QString CustomFrameOnStlye = QString("QAbstractButton { border: none; border-radius: %1; background-color: #4697D9;}").arg(FrameSize.height() / 2);
13 static const QString CustomFrameOffStlye = QString("QAbstractButton { border: none; border-radius: %1; background-color: #6f80ab;}").arg(FrameSize.height() / 2);
14 static const QString CustomButtonStlye = QString("QPushButton { min-width: 0em; border-radius: %1; background-color: white;}").arg(SwitchSize.height() / 2);
15
QSwitchControl(QWidget * parent)16 QSwitchControl::QSwitchControl(QWidget *parent):
17 QAbstractButton(parent)
18 {
19 this->setFixedSize(FrameSize);
20
21 pbSwitch = new QPushButton(this);
22 pbSwitch->setFixedSize(SwitchSize);
23 pbSwitch->setStyleSheet(CustomButtonStlye);
24
25 animation = new QPropertyAnimation(pbSwitch, "geometry", this);
26 animation->setDuration(200);
27
28 connect(this, &QSwitchControl::mouseClicked, this, &QSwitchControl::onStatusChanged);
29 connect(pbSwitch, &QPushButton::clicked, this, &QSwitchControl::onStatusChanged);
30 setCheckable(true);
31 setChecked(false);
32 }
33
setChecked(bool checked)34 void QSwitchControl::setChecked(bool checked)
35 {
36 if(checked)
37 {
38 pbSwitch->move(this->width() - pbSwitch->width() - SwitchOffset, this->y() + SwitchOffset);
39 this->setStyleSheet(CustomFrameOnStlye);
40 }
41 else
42 {
43 pbSwitch->move(this->x() + SwitchOffset, this->y() + SwitchOffset);
44 this->setStyleSheet(CustomFrameOffStlye);
45 }
46
47 QAbstractButton::setChecked(checked);
48 }
49
onStatusChanged()50 void QSwitchControl::onStatusChanged()
51 {
52 bool checked = !isChecked();
53
54 QRect currentGeometry(pbSwitch->x(), pbSwitch->y(), pbSwitch->width(), pbSwitch->height());
55
56 if(animation->state() == QAbstractAnimation::Running)
57 animation->stop();
58
59 if(checked)
60 {
61 this->setStyleSheet(CustomFrameOnStlye);
62
63 animation->setStartValue(currentGeometry);
64 animation->setEndValue(QRect(this->width() - pbSwitch->width() - SwitchOffset, pbSwitch->y(), pbSwitch->width(), pbSwitch->height()));
65 }
66 else
67 {
68 this->setStyleSheet(CustomFrameOffStlye);
69
70 animation->setStartValue(currentGeometry);
71 animation->setEndValue(QRect(SwitchOffset, pbSwitch->y(), pbSwitch->width(), pbSwitch->height()));
72 }
73 animation->start();
74
75 setChecked(checked);
76 Q_EMIT clicked(checked);
77 }
78
mousePressEvent(QMouseEvent *)79 void QSwitchControl::mousePressEvent(QMouseEvent *)
80 {
81 Q_EMIT mouseClicked();
82 }
83
paintEvent(QPaintEvent *)84 void QSwitchControl::paintEvent(QPaintEvent *)
85 {
86 QStyleOption opt;
87 opt.init(this);
88 QPainter p(this);
89 style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
90 }
91