//.h文件#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QPainter>
#include<QMouseEvent>
#include<QPropertyAnimation>
#include<QResizeEvent>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
protected:void paintEvent(QPaintEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void resizeEvent(QResizeEvent *event)override;private:Ui::Widget *ui;bool isOff = true;QBrush offBgBrush = Qt::black;QBrush onBgBrush = Qt::blue;QBrush offIndIndiicatorBrush = Qt::red;QBrush onIndIndiicatorBrush = Qt::green;QString offtext = "OFF";QString ontext = "ON";QPropertyAnimation *ani;int current_x;};
#endif // WIDGET_H
.cpp 源文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ani = new QPropertyAnimation(this);ani->setTargetObject(this);ani->setDuration(300);ani->setEasingCurve(QEasingCurve::InOutBack);current_x=height()/2;connect(ani,&QPropertyAnimation::valueChanged,this,[=](const QVariant& value){current_x=value.toInt();update();});}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event){Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing,true);painter.setPen(Qt::NoPen);painter.setBrush(isOff?offBgBrush:onBgBrush);painter.drawRoundedRect(this->rect(),height()/2,height()/2);painter.setBrush(isOff?offIndIndiicatorBrush:onIndIndiicatorBrush);
// QPoint center;
// isOff ? center=QPoint(height()/2,height()/2):center=QPoint(width()-height()/2,height()/2);
// painter.drawEllipse(center,height()/2-10,height()/2-10);painter.drawEllipse(QPoint(current_x,height()/2),height()/2-10,height()/2-10);painter.setPen(Qt::white);painter.setFont(QFont("楷体",30));painter.drawText(this->rect(),Qt::AlignCenter,isOff?offtext:ontext);}void Widget::mousePressEvent(QMouseEvent *event){if(event->button()==Qt::LeftButton){isOff?ani->setDirection(QVariantAnimation::Forward):ani->setDirection(QVariantAnimation::Backward);isOff = !isOff;ani->start();}
}void Widget::resizeEvent(QResizeEvent *event){ani->setStartValue(height()/2);ani->setEndValue(width()-height()/2);}
pyhong实现代码:
import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *class Switch(QWidget):def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)self._isOff = Trueself._offBgBrush:QBrush = Qt.blackself._onBgBrush: QBrush = Qt.blueself._offIndiicatorBrush: QBrush = Qt.redself._onIndiicatorBrush: QBrush = Qt.greenself._offText :str ="OFF"self._onText: str = "On"self.current_x:int = self.height()/2#动画self._ani = QPropertyAnimation(self)self._ani.setTargetObject(self)self._ani.setDuration(300)self._ani.setEasingCurve(QEasingCurve.Type.InOutBack)self._ani.valueChanged.connect(self._ani_value_changed)def paintEvent(self, event):painter = QPainter(self)painter.setRenderHint(QPainter.RenderHint.Antialiasing,True)painter.setPen(Qt.PenStyle.NoPen)painter.setBrush(self._offBgBrush if self._isOff else self._onBgBrush)painter.drawRoundedRect(self.rect(),self.height()/2,self.height()/2)painter.setBrush(self._offIndiicatorBrush if self._isOff else self._onIndiicatorBrush)length:int = int(self.height()/2)painter.drawEllipse(QPoint(self.current_x,self.height()/2),length-10,length-10)painter.setPen(Qt.white)painter.setFont(QFont("楷体",30))painter.drawText(self.rect(),Qt.AlignmentFlag.AlignCenter,self._offText if self._isOff elseself._onText)return super().paintEvent(event)def mousePressEvent(self, event):if event.button()==Qt.MouseButton.LeftButton:if self._isOff:self._ani.setDirection(QVariantAnimation.Direction.Forward)else:self._ani.setDirection(QVariantAnimation.Direction.Backward)self._isOff = not self._isOffself._ani.start()return super().mousePressEvent(event)def resizeEvent(self, event):self._ani.setStartValue(self.height()/2)self._ani.setEndValue(self.width()-self.height()/2)return super().resizeEvent(event)def _ani_value_changed(self,value):self.current_x = int(value)self.update()if __name__ == '__main__':app = QApplication(sys.argv)win = Switch()win.show()sys.exit(app.exec())
运行效果: