PyQt实现滑动按钮

         最近在练习PyQt时,突发奇想在qt中有没有滑动按钮,经过一顿搜索,最终找到一位大佬写的按钮类(原文点这里),但是我发现他在实际运用时,还是有一点问题,就是小球各种参数需要自己进行微调,才能调出一个适合的按钮,于是我在此基础上完善了参数需要微调的问题,并新增用户调节颜色接口,以及滑动时间接口,最后增加了程序主动触发按钮函数,这个函数详情在我的上一个文章里(点这里),让这个滑动按钮更加简便。

一、效果图

示意图

二、效果图

# coding: utf-8
# @Author: 小杨大帅哥
from PyQt5.QtCore import QPoint, QCoreApplication, Qt, QRectF
from PyQt5.QtGui import QMouseEvent, QColor, QPainter
from PyQt5.QtWidgets import QAbstractButton


class SlidButton(QAbstractButton):
    def __init__(self, *args,
                 # 滑动总时间, 单位: s
                 slip_time=.3,
                 # 按钮未滑动小圆颜色
                 inner_color=QColor(89, 89, 89),
                 # 按钮滑动后小圆颜色
                 checked_inner_color=QColor(255, 255, 255),
                 # 按钮未滑动背景颜色
                 outer_color=QColor(212, 212, 212),
                 # 按钮滑动后背景颜色
                 checked_outer_color=QColor(51, 153, 255)):
        super(SlidButton, self).__init__(*args)
        self.__offset = None
        self.__beginning_offset = None
        self.__innerMargin = None
        self.__innerDiameter = None
        # 总滑动时间
        self.__slipTime = slip_time * 1000
        # 是否选中标志位
        self.__checked = False
        # 定时器ID
        self.__timeId = None
        # 鼠标形状
        self.setCursor(Qt.PointingHandCursor)
        self.__innerColor = inner_color
        self.__checkedInnerColor = checked_inner_color
        self.__outerColor = outer_color
        self.__checkedOuterColor = checked_outer_color

    def resizeEvent(self, event):
        super(SlidButton, self).resizeEvent(event)
        # 内部圆直径, 一般设置比高度小一点就可以了
        self.__innerDiameter = self.height() - self.height() // 8
        # 内边距
        self.__innerMargin = 0
        # 初始时刻小球左边缘距离边框在x坐标的偏移量
        self.__offset = (self.width() - self.__innerDiameter) // 20
        self.__beginning_offset = self.__offset

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(Qt.NoPen)
        # 开启抗锯齿
        painter.setRenderHint(QPainter.Antialiasing)

        # 根据不同的选中状态切换内外颜色
        if self.__checked:
            __innerColor = self.__checkedInnerColor
            __outerColor = self.__checkedOuterColor
        else:
            __innerColor = self.__innerColor
            __outerColor = self.__outerColor

        # 画外部圆角矩形
        painter.setBrush(__outerColor)
        painter.drawRoundedRect(self.rect(), self.height() // 2, self.height() // 2)

        # 画内部圆形
        painter.setBrush(__innerColor)
        painter.drawEllipse(QRectF(self.__offset,
                                   (self.height() - self.__innerDiameter) // 2,
                                   self.__innerDiameter,
                                   self.__innerDiameter))

    def timerEvent(self, event):
        # 根据选中状态修改x坐标偏移值
        if self.__checked:
            self.__offset += 1
            # 圆球的位置要保持在圆框范围之内偏移
            if self.__offset >= (self.width() - self.__innerDiameter - self.__beginning_offset):
                self.killTimer(self.__timeId)
        else:
            self.__offset -= 1
            if self.__offset <= self.__beginning_offset:
                self.killTimer(self.__timeId)
        # 调用update,进行重绘
        self.update()

    def killTimer(self, __timeId):
        # 删除定时器的同时,将timeId置为None
        super(SlidButton, self).killTimer(__timeId)
        self.__timeId = None

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.__checked = not self.__checked
            self.toggled.emit(self.__checked)
            if self.__timeId:
                self.killTimer(self.__timeId)
            self.__timeId = self.startTimer(self.__slipTime // (self.width() -
                                                                self.__innerDiameter - self.__beginning_offset))

    def isChecked(self):
        return self.__checked

    def fake_clicked(self):
        """
        程序模仿人为操作按下按钮
        """
        QCoreApplication.postEvent(self,
                                   QMouseEvent(QMouseEvent.MouseButtonRelease,
                                               self.mapToGlobal(QPoint(0, 0)),
                                               self.mapToGlobal(QPoint(0, 0)),
                                               Qt.LeftButton,
                                               Qt.LeftButton,
                                               Qt.NoModifier))

三、参数详解

滑动按钮参数如下
1. 滑动总时间, 单位s:slip_time
2.按钮未滑动小圆颜色inner_color
3. 按钮滑动后小圆颜色:checked_inner_color
4. 按钮未滑动背景颜色: outer_color
5. 按钮滑动后背景颜色:checked_outer_color
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值