Qt自定义QpushButton分别在c++/python中实现

//.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_OBJECT

public:
    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 = True
        self._offBgBrush:QBrush = Qt.black
        self._onBgBrush: QBrush = Qt.blue
        self._offIndiicatorBrush: QBrush = Qt.red
        self._onIndiicatorBrush: QBrush = Qt.green
        self._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 else
                         self._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._isOff
            self._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())








运行效果:

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值