界面修改以及显示
This commit is contained in:
126
view/widgets/switch_button.py
Normal file
126
view/widgets/switch_button.py
Normal file
@ -0,0 +1,126 @@
|
||||
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())
|
||||
Reference in New Issue
Block a user