增加系统设置弹窗(包括多段振捣设置、IP设置)

This commit is contained in:
yaj
2026-04-08 18:33:30 +08:00
parent 5e8f291738
commit 8a08b57c45
4 changed files with 1666 additions and 0 deletions

View File

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
"""
ArrowComboBox - 带动态箭头的下拉框组件
展开时箭头向上,收起时箭头向下
"""
import os
import re
import tempfile
from PySide6.QtWidgets import QComboBox
from PySide6.QtGui import QPixmap, QPainter, QTransform, QPolygonF
from PySide6.QtCore import Qt, Signal, QTimer, QPointF
from utils.image_paths import ImagePaths
class ArrowComboBox(QComboBox):
"""带动态箭头的下拉框,展开时箭头向上,收起时箭头向下
Signals:
popupShown: 下拉列表展开时发出
popupHidden: 下拉列表收起时发出
arrowDirectionChanged: 箭头方向改变时发出 (is_up: bool)
"""
# 信号定义
popupShown = Signal() # 下拉列表展开
popupHidden = Signal() # 下拉列表收起
arrowDirectionChanged = Signal(bool) # 箭头方向改变 (True=向上, False=向下)
# 类缓存
_arrow_down_path = None # 向下箭头图片路径
_arrow_up_path = None # 向上箭头图片路径
_initialized = False # 是否已初始化
@classmethod
def init_arrow_resources(cls, arrow_image_path: str = None, arrow_size: tuple = (14, 8)):
"""初始化箭头资源(类方法,只需调用一次)
Args:
arrow_image_path: 自定义箭头图片路径,默认使用 ImagePaths.SYSTEM_DIAGNOSTICS_DROPDOWN_ARROW
arrow_size: 箭头尺寸 (width, height),默认 (14, 8)
"""
if cls._initialized:
return
arrow_width, arrow_height = arrow_size
# 加载原始箭头图片
if arrow_image_path is None:
arrow_image_path = ImagePaths.SYSTEM_DIAGNOSTICS_DROPDOWN_ARROW
original = QPixmap(arrow_image_path)
if original.isNull():
# 如果加载失败,创建默认箭头
original = QPixmap(arrow_width, arrow_height)
original.fill(Qt.transparent)
painter = QPainter(original)
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(Qt.NoPen)
painter.setBrush(Qt.white)
points = [
QPointF(1, 1),
QPointF(arrow_width - 1, 1),
QPointF(arrow_width / 2, arrow_height - 1)
]
painter.drawPolygon(QPolygonF(points))
painter.end()
down_pixmap = original.scaled(arrow_width, arrow_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
# 垂直翻转得到向上箭头
transform = QTransform()
transform.scale(1, -1)
up_pixmap = down_pixmap.transformed(transform)
# 保存到临时文件
temp_dir = tempfile.gettempdir()
cls._arrow_down_path = os.path.join(temp_dir, "arrow_down.png").replace("\\", "/")
cls._arrow_up_path = os.path.join(temp_dir, "arrow_up.png").replace("\\", "/")
down_pixmap.save(cls._arrow_down_path, "PNG")
up_pixmap.save(cls._arrow_up_path, "PNG")
cls._initialized = True
@classmethod
def get_arrow_paths(cls):
"""获取箭头图片路径
Returns:
tuple: (向下箭头路径, 向上箭头路径)
"""
return cls._arrow_down_path, cls._arrow_up_path
def __init__(self, parent=None):
super().__init__(parent)
ArrowComboBox.init_arrow_resources()
self._is_open = False
self._updating_style = False
self._arrow_size = (14, 8) # 默认箭头尺寸
# 延迟初始化箭头(等待样式设置后)
QTimer.singleShot(0, self._update_arrow_style)
@property
def isPopupOpen(self) -> bool:
"""返回下拉列表是否打开"""
return self._is_open
@property
def arrowDirection(self) -> str:
"""返回当前箭头方向 ('up''down')"""
return 'up' if self._is_open else 'down'
def setArrowSize(self, width: int, height: int):
"""设置箭头尺寸
Args:
width: 箭头宽度
height: 箭头高度
"""
self._arrow_size = (width, height)
self._update_arrow_style()
def setArrowDirection(self, is_up: bool):
"""手动设置箭头方向
Args:
is_up: True 为向上False 为向下
"""
if self._is_open != is_up:
self._is_open = is_up
self._update_arrow_style()
self.arrowDirectionChanged.emit(is_up)
def showPopup(self):
"""展开下拉列表时切换为向上箭头"""
super().showPopup()
self._is_open = True
self._update_arrow_style()
self.popupShown.emit()
self.arrowDirectionChanged.emit(True)
def hidePopup(self):
"""收起下拉列表时切换为向下箭头"""
super().hidePopup()
self._is_open = False
self._update_arrow_style()
self.popupHidden.emit()
self.arrowDirectionChanged.emit(False)
def togglePopup(self):
"""切换下拉列表的展开/收起状态"""
if self._is_open:
self.hidePopup()
else:
self.showPopup()
def refreshArrowStyle(self):
"""刷新箭头样式(外部调用)"""
self._update_arrow_style()
def _update_arrow_style(self):
"""更新箭头样式(内部方法)"""
if self._updating_style:
return
self._updating_style = True
try:
arrow_path = self._arrow_up_path if self._is_open else self._arrow_down_path
arrow_width, arrow_height = self._arrow_size
style = self.styleSheet()
# 移除旧的箭头样式
style = re.sub(r'QComboBox::down-arrow\s*\{[^}]*\}', '', style)
style += f"""QComboBox::down-arrow {{ image: url({arrow_path}); width: {arrow_width}px; height: {arrow_height}px; }}"""
super().setStyleSheet(style)
finally:
self._updating_style = False