Files
Feeding_control_system/view/widgets/switch_button.py
2025-10-31 18:52:35 +08:00

127 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from PySide6.QtWidgets import (
QAbstractButton,
QApplication,
QSizePolicy,
QWidget,
QVBoxLayout,
)
from PySide6.QtCore import Qt, QRect, Signal
from PySide6.QtGui import QPainter, QBrush
class SwitchButton(QAbstractButton):
# 开关切换信号
# 开: True, 关: False
switched = Signal(bool)
def __init__(self, parent=None):
super().__init__(parent)
self._checked = False
self.setCursor(Qt.CursorShape.PointingHandCursor)
# 颜色映射
self.color_keymap = {
"slider": "#16ffff",
"text": Qt.GlobalColor.white,
"on_bg": "#008ee8", # 开的时候的背景颜色
"off_bg": "#001c83", # 关的时候的背景颜色
}
self.clicked.connect(self.onClicked)
self._init_style() # 新尺寸的样式表
self._init_size_policy()
def _init_style(self):
self.setStyleSheet(
"""
SwitchButton {
font-family: "Microsoft YaHei";
font-size: 11px;
color: white;
border-radius: 9px;
margin: 2px;
min-width: 39px;
max-width: 39px;
min-height: 18px;
max-height: 18px;
}
"""
)
def _init_size_policy(self):
self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
def paintEvent(self, event):
# 1. 调整滑块间距
slider_space = 1 # 滑块与背景的间距上下左右各1px
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
try:
# 2. 绘制背景
background_rect = self.rect()
painter.setPen(Qt.PenStyle.NoPen)
bg_color = (
self.color_keymap["on_bg"]
if self._checked
else self.color_keymap["off_bg"]
)
painter.setBrush(QBrush(bg_color))
painter.drawRoundedRect(
background_rect, self.height() / 2, self.height() / 2
)
# 3. 计算新滑块尺寸
slider_width = self.height() - slider_space * 2
# 4. 计算新滑块位置
if self._checked:
slider_x = self.width() - slider_width - slider_space
else:
slider_x = slider_space
slider_y = slider_space
# 5. 绘制滑块
slider_rect = QRect(slider_x, slider_y, slider_width, slider_width)
painter.setBrush(QBrush(self.color_keymap["slider"]))
painter.drawEllipse(slider_rect)
finally:
painter.end()
def onClicked(self):
self._checked = not self._checked
self.update()
self.switched.emit(self._checked)
def setChecked(self, checked: bool):
self._checked = checked
self.update()
self.switched.emit(self._checked)
def isChecked(self) -> bool:
return self._checked
# 测试示例
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
test_window = QWidget()
test_window.setWindowTitle("开关测试")
test_window.resize(200, 100)
layout = QVBoxLayout(test_window)
layout.setContentsMargins(50, 30, 50, 30)
switch = SwitchButton()
switch.switched.connect(
lambda state: print(f"开关状态:{'选中' if state else '未选中'}")
)
layout.addWidget(switch)
test_window.show()
sys.exit(app.exec())