Files
Feeding_control_system/view/widgets/system_center_dialog.py
2025-11-01 16:13:30 +08:00

152 lines
6.2 KiB
Python
Raw 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 (QApplication, QVBoxLayout, QPushButton, QDialog)
from PySide6.QtGui import QPixmap, QFont, QIcon, QPainter
from PySide6.QtCore import Qt, Signal
from PySide6.QtCore import Qt, Signal, QPropertyAnimation, QEasingCurve, QRect
import sys
import resources.resources_rc
from utils.image_paths import ImagePaths
class CustomButton(QPushButton):
def __init__(self, text, normal_icon, active_icon, parent=None):
super().__init__(text, parent)
self.normal_icon = normal_icon
self.active_icon = active_icon
self.setFixedSize(147, 36)
self.setCursor(Qt.PointingHandCursor)
self.update_icon(self.normal_icon)
self.setFont(QFont("", 17))
self.setStyleSheet("""
QPushButton {
color: #16ffff;
background: none;
outline: none;
border: none;
text-align: center;
background-color: transparent;
font-weight: Bold;
}
QPushButton:hover {
color: #001c83;
background-color: #16ffff;
background-repeat: no-repeat;
outline: none;
border: none;
}
""")
def update_icon(self, icon_path):
pixmap = QPixmap(icon_path)
if not pixmap.isNull():
scaled_pixmap = pixmap.scaled(24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.setIcon(QIcon(scaled_pixmap))
self.setIconSize(scaled_pixmap.size())
else:
self.setIcon(QIcon())
def enterEvent(self, event):
self.update_icon(self.active_icon)
super().enterEvent(event)
def leaveEvent(self, event):
self.update_icon(self.normal_icon)
super().leaveEvent(event)
class SystemCenterDialog(QDialog):
# 定义三个信号,对应三个按钮的点击事件
sys_setting_clicked = Signal() # 系统设置点击信号
data_center_clicked = Signal() # 数据中心点击信号
user_center_clicked = Signal() # 用户中心点击信号
def __init__(self, parent=None):
super().__init__(parent)
self.init_ui()
self.init_animations() # 初始化动画
def init_ui(self):
# 弹窗基础设置
self.setWindowTitle("系统中心")
self.setWindowFlags(Qt.FramelessWindowHint) # 隐藏默认边框
self.setWindowOpacity(0.0) # 初始状态为完全透明,实现动画效果
# 加载背景图
self.background = QPixmap(ImagePaths.SYSTEM_CENTER_POPUP_BG)
if self.background.isNull():
print("警告:系统中心弹窗背景.png 加载失败!")
self.setFixedSize(220, 200)
else:
self.setFixedSize(self.background.size())
# 主布局
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 6)
main_layout.setSpacing(0)
main_layout.setAlignment(Qt.AlignCenter)
# 创建按钮并绑定信号发射
self.sys_btn = CustomButton("系统设置", ImagePaths.SYSTEM_SETTING_BG1, ImagePaths.SYSTEM_SETTING_BG2)
self.data_btn = CustomButton("数据中心", ImagePaths.SYSTEM_DATA_CENTER_BG1, ImagePaths.SYSTEM_DATA_CENTER_BG2)
self.user_btn = CustomButton("用户中心", ImagePaths.SYSTEM_USER_CENTER_BG1, ImagePaths.SYSTEM_USER_CENTER_BG2)
# 按钮点击 → 发射对应信号dialog不处理业务逻辑只传递事件
self.sys_btn.clicked.connect(self.sys_setting_clicked.emit)
self.data_btn.clicked.connect(self.data_center_clicked.emit)
self.user_btn.clicked.connect(self.user_center_clicked.emit)
main_layout.addWidget(self.sys_btn)
main_layout.addWidget(self.data_btn)
main_layout.addWidget(self.user_btn)
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.background)
super().paintEvent(event)
def init_animations(self):
"""初始化显示动画(可根据喜好选择或组合)"""
# 1. 淡入动画透明度从0→1
self.opacity_anim = QPropertyAnimation(self, b"windowOpacity")
self.opacity_anim.setDuration(300) # 动画时长300ms
self.opacity_anim.setStartValue(0.0)
self.opacity_anim.setEndValue(1.0)
self.opacity_anim.setEasingCurve(QEasingCurve.InOutCubic) # 缓动曲线(平滑加速减速)
# 2. 缩放动画从80%→100%大小)
self.scale_anim = QPropertyAnimation(self, b"geometry")
self.scale_anim.setDuration(300)
# 起点和终点在显示时动态设置(依赖当前弹窗位置)
self.scale_anim.setEasingCurve(QEasingCurve.OutBack) # 带弹性的缓动曲线(弹出感)
# 3. 组合动画(同时执行淡入+缩放)
from PySide6.QtCore import QParallelAnimationGroup
self.anim_group = QParallelAnimationGroup(self)
self.anim_group.addAnimation(self.opacity_anim)
self.anim_group.addAnimation(self.scale_anim)
def showEvent(self, event):
"""重写显示事件,每次显示时启动动画"""
# 必须先调用父类showEvent否则弹窗无法正常显示
super().showEvent(event)
# 动态设置缩放动画的起点(基于当前弹窗位置和大小)
current_geometry = self.geometry() # 弹窗当前位置和大小已通过move设置
# 起点缩小到80%,并保持中心位置不变
start_rect = QRect(
current_geometry.center().x() - current_geometry.width() * 0.4,
current_geometry.center().y() - current_geometry.height() * 0.4,
int(current_geometry.width() * 0.8),
int(current_geometry.height() * 0.8)
)
self.scale_anim.setStartValue(start_rect)
self.scale_anim.setEndValue(current_geometry) # 终点:原始大小
# 启动组合动画
self.anim_group.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
dialog = SystemCenterDialog()
# 测试信号(实际业务在控制器中绑定)
dialog.sys_setting_clicked.connect(lambda: print("系统设置被点击"))
dialog.show()
sys.exit(app.exec())