PyQt5实现滑动开关的示例详解

效果图

1、初始化按钮类

class SwitchButton(QPushButton):
    def __init__(self):
        super().__init__()

SwitchButton 是一个继承自 QPushButton 的自定义按钮类。

在初始化函数中,调用了 super().__init__(),确保父类 QPushButton 的初始化功能被执行。

2、设置按钮的基础样式

self.setCheckable(True)  # 使按钮可以选中和取消选中
self.setStyleSheet("""
    SwitchButton {
        border: 2px solid #ccc;
        border-radius: 15px;
        background-color: #ccc;
        width: 80px;  /* 增加宽度 */
        height: 30px;
        position: relative;
    }
    SwitchButton:checked {
        background-color: #4CAF50;
    }
""")
self.setFixedSize(80, 30)

设置按钮为 可选中状态 (checkable),即可以切换选中和未选中状态。

使用 setStyleSheet 设置按钮的样式:

  • 默认情况下背景色为灰色(#ccc)。
  • 选中状态(SwitchButton:checked)时背景色为绿色(#4CAF50)。
  • 按钮有圆角边框(border-radius: 15px),形状为椭圆。

固定按钮的大小为 80×30 像素。

3、添加滑块

self._slider = QPushButton(self)  # 用于滑动的按钮
self._slider.setFixedSize(28, 28)
self._slider.setStyleSheet("""
    QPushButton {
        border-radius: 14px;
        background-color: white;
    }
""")
self._slider.move(2, 2)  # 初始位置

self._slider 是一个内部的小按钮,用于表示开关滑块。

设置滑块的大小为 28×28,并使用 border-radius: 14px 将其形状设置为圆形。

初始位置通过 move(2, 2) 放置在按钮左侧。

4、添加状态文本

self._label = QLabel("OFF", self)
self._label.setStyleSheet("""
    QLabel {
        color: white;
        font-weight: bold;
    }
""")
self._label.setFixedSize(40, 30)
self._label.move(20, 0)  # 初始位置为中间位置

self._label 是用于显示当前按钮状态的文本。

设置了 OFF 为初始文本,并通过样式设置文本为白色,字体加粗。

使用 move(20, 0) 将文本放置在按钮的中间位置。

5、设置动画效果

self.animation = QPropertyAnimation(self._slider, b"pos")
self.animation.setDuration(200)  # 动画持续时间

self.animation 是一个属性动画,用于在滑块滑动时产生平滑的过渡效果。

将滑块的 pos 属性绑定到动画中,动画的持续时间设置为 200 毫秒。

6、切换按钮的状态

self.clicked.connect(self.toggle)

通过 clicked.connect 将按钮的点击事件与自定义的 toggle 方法绑定。

7、实现状态切换逻辑

def toggle(self):
    if self.isChecked():
        self.animation.setEndValue(QPoint(50, 2))  # 开关打开时滑块的位置
        self._label.setText("ON")  # 更新文本为 ON
        self._label.move(20, 0)  # 保持文本在中间位置
    else:
        self.animation.setEndValue(QPoint(2, 2))  # 开关关闭时滑块的位置
        self._label.setText("OFF")  # 更新文本为 OFF
        self._label.move(20, 0)  # 保持文本在中间位置
    self.animation.start()

判断按钮状态:

  • 使用 isChecked() 检查按钮是否处于选中状态。
  • 如果选中(ON 状态),将滑块的目标位置设置为按钮右侧(QPoint(50, 2))。
  • 如果未选中(OFF 状态),将滑块的目标位置设置为按钮左侧(QPoint(2, 2))。

更新状态文本:

  • 在 ON 状态下,文本更新为 ON。
  • 在 OFF 状态下,文本更新为 OFF。
  • 文本始终放在按钮的中间位置。

启动动画:

调用 self.animation.start() 启动滑块动画。

import sys
from PyQt5.QtCore import QPropertyAnimation, QPoint
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel


class SwitchButton(QPushButton):
    def __init__(self):
        super().__init__()

        self.setCheckable(True)  # 使按钮可以选中和取消选中
        self.setStyleSheet("""
            SwitchButton {
                border: 2px solid #ccc;
                border-radius: 15px;
                background-color: #ccc;
                 width: 80px;  /* 增加宽度 */
                height: 30px;
                position: relative;
            }
            SwitchButton:checked {
                background-color: #4CAF50;
            }
        """)
        self.setFixedSize(80, 30)

        self._slider = QPushButton(self)  # 用于滑动的按钮
        self._slider.setFixedSize(28, 28)
        self._slider.setStyleSheet("""
            QPushButton {
                border-radius: 14px;
                background-color: white;
            }
        """)
        self._slider.move(2, 2)  # 初始位置

        # 添加状态文本标签
        self._label = QLabel("OFF", self)
        self._label.setStyleSheet("""
                    QLabel {
                        color: white;
                        font-weight: bold;
                    }
                """)
        self._label.setFixedSize(40, 30)
        self._label.move(40, 0)  # 初始位置为中间位置

        # 动画效果
        self.animation = QPropertyAnimation(self._slider, b"pos")
        self.animation.setDuration(200)  # 动画持续时间

        # 点击事件切换开关
        self.clicked.connect(self.toggle)

    def toggle(self):
        if self.isChecked():
            self.animation.setEndValue(QPoint(50, 2))  # 开关打开时滑块的位置
            self._label.setText("ON")  # 更新文本为 ON
            self._label.move(20, 0)  # 保持文本在中间位置
        else:
            self.animation.setEndValue(QPoint(2, 2))  # 开关关闭时滑块的位置
            self._label.setText("OFF")  # 更新文本为 OFF
            self._label.move(40, 0)  # 保持文本在中间位置
        self.animation.start()


class App(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('PyQt5 Switch Button Example')
        self.setGeometry(300, 300, 200, 100)

        layout = QVBoxLayout()
        self.switch_button = SwitchButton()
        layout.addWidget(self.switch_button)
        self.setLayout(layout)
        self.switch_button.clicked.connect(self.on_state_changed)

    def on_state_changed(self):
        if self.switch_button.isChecked():
            print("Switch is ON")
        else:
            print("Switch is OFF")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = App()
    window.show()
    sys.exit(app.exec_())

到此这篇关于PyQt5实现滑动开关的示例详解的文章就介绍到这了,更多相关PyQt5滑动开关内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源链接:https://www.jb51.net/program/332237dkd.htm

© 版权声明
THE END
支持一下吧
点赞12 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容