Files
Feeding_control_system/controller/bottom_control_controller.py

194 lines
9.5 KiB
Python
Raw Normal View History

2025-10-31 18:52:31 +08:00
# controller/bottom_control_controller.py
from PySide6.QtCore import Qt, QPropertyAnimation, QRect, QParallelAnimationGroup, QEasingCurve
from view.widgets.system_center_dialog import SystemCenterDialog
from view.widgets.bottom_control_widget import BottomControlWidget
2025-11-07 15:45:54 +08:00
from view.widgets.system_diagnostics_dialog import SystemDiagnosticsDialog
2025-10-31 18:52:31 +08:00
"""
控制主界面底部的所有按钮, 包括系统诊断系统中心等的行为
以及 版本信息相关弹窗, : v1.0
"""
class BottomControlController:
def __init__(self, bottom_control_widget:BottomControlWidget, main_window):
self.bottom_control_widget = bottom_control_widget
self.main_window = main_window
self._bind_buttons()
# 系统中心弹窗
self.system_center_dialog = SystemCenterDialog(self.main_window)
self.system_center_dialog.hide() # 初始隐藏 (必须)
self._init_system_center_dialog_hide_animations()
2025-11-07 15:45:54 +08:00
# 系统诊断弹窗
self.system_diagnostics_dialog = SystemDiagnosticsDialog(self.main_window)
self.system_diagnostics_dialog.hide()
self._init_system_diagnostics_dialog_hide_animations()
2025-10-31 18:52:31 +08:00
self._bind_dialog_signals()
def _bind_buttons(self):
# 底部系统中心按钮 → 触发弹窗显示/隐藏
self.bottom_control_widget.center_btn.clicked.connect(self.toggle_system_center_dialog)
2025-11-07 15:45:54 +08:00
# 底部系统诊断按钮 → 触发弹窗显示/隐藏
self.bottom_control_widget.diagnosis_btn.clicked.connect(self.toggle_system_diagnostics_dialog)
2025-10-31 18:52:31 +08:00
def _bind_dialog_signals(self):
"""绑定弹窗按钮的信号"""
self.system_center_dialog.sys_setting_clicked.connect(self.handle_sys_setting)
self.system_center_dialog.data_center_clicked.connect(self.handle_data_center)
self.system_center_dialog.user_center_clicked.connect(self.handle_user_center)
def _init_system_center_dialog_hide_animations(self):
"""初始化系统中心弹窗隐藏动画(淡出+缩小,与显示动画对应)"""
# 1. 淡出动画
self.hide_opacity_anim = QPropertyAnimation(self.system_center_dialog, b"windowOpacity", self.system_center_dialog)
self.hide_opacity_anim.setDuration(200)
self.hide_opacity_anim.setStartValue(1.0)
self.hide_opacity_anim.setEndValue(0.0)
# 2. 缩小动画
self.hide_scale_anim = QPropertyAnimation(self.system_center_dialog, b"geometry", self.system_center_dialog)
self.hide_scale_anim.setDuration(200)
self.hide_scale_anim.setEasingCurve(QEasingCurve.InBack) # 收缩感
# 3. 组合动画(父对象设为弹窗)
self.hide_anim_group = QParallelAnimationGroup(self.system_center_dialog)
self.hide_anim_group.addAnimation(self.hide_opacity_anim)
self.hide_anim_group.addAnimation(self.hide_scale_anim)
# 动画结束后,强制隐藏弹窗
self.hide_anim_group.finished.connect(self.system_center_dialog.hide)
def toggle_system_center_dialog(self):
2025-11-07 15:45:54 +08:00
"""切换系统中心弹窗的显示/隐藏状态"""
2025-10-31 18:52:31 +08:00
if self.system_center_dialog.isVisible():
# 已显示 → 隐藏
# self.system_center_dialog.hide()
# 动态设置缩小动画的起点和终点(基于当前弹窗位置)
current_geo = self.system_center_dialog.geometry()
end_rect = QRect(
current_geo.center().x() - current_geo.width() * 0.4,
current_geo.center().y() - current_geo.height() * 0.4,
int(current_geo.width() * 0.8),
int(current_geo.height() * 0.8)
)
self.hide_scale_anim.setStartValue(current_geo)
self.hide_scale_anim.setEndValue(end_rect)
# 启动隐藏动画 (隐藏动画结束,自动隐藏 系统中心弹窗)
self.hide_anim_group.start()
else:
# 未显示 → 计算位置并显示
self._calc_system_center_dialog_position() # 每次显示都计算位置
self.system_center_dialog.show()
def _calc_system_center_dialog_position(self):
"""计算系统中心弹窗位置, 并move移动"""
btn = self.bottom_control_widget.center_btn
bottom_widget = self.bottom_control_widget
# 计算按钮相对于主窗口的位置
bottom_pos_rel_main = bottom_widget.pos()
btn_pos_rel_bottom = btn.pos()
btn_pos_rel_main = bottom_pos_rel_main + btn_pos_rel_bottom
# 计算弹窗坐标
btn_width = btn.width()
dialog_size = self.system_center_dialog.size()
dialog_x = btn_pos_rel_main.x() + (btn_width - dialog_size.width()) // 2
dialog_y = btn_pos_rel_main.y() - dialog_size.height()
# 设置弹窗位置
self.system_center_dialog.move(dialog_x, dialog_y)
2025-11-07 15:45:54 +08:00
# ------------------- 系统中心弹窗业务逻辑-------------------
2025-10-31 18:52:31 +08:00
def handle_sys_setting(self):
"""系统设置按钮的业务逻辑"""
# print("执行系统设置逻辑:如打开系统配置窗口、修改参数等")
# 示例:打开系统配置弹窗(后续可新建 SystemSettingDialog
# setting_dialog = SystemSettingDialog(self.main_window)
# setting_dialog.exec()
def handle_data_center(self):
"""数据中心按钮的业务逻辑"""
# print("执行数据中心逻辑:如查看生产数据、导出报表等")
def handle_user_center(self):
"""用户中心按钮的业务逻辑"""
2025-11-07 15:45:54 +08:00
# print("执行用户中心逻辑:如切换用户、修改密码等")
# ------------------- 系统诊断弹窗逻辑-------------------
def _init_system_diagnostics_dialog_hide_animations(self):
"""初始化系统诊断弹窗隐藏动画(与显示动画反向:滑出+淡出)"""
# 1. 淡出动画(与显示动画时长一致)
self.dia_hide_opacity_anim = QPropertyAnimation(
self.system_diagnostics_dialog, b"windowOpacity", self.system_diagnostics_dialog
)
self.dia_hide_opacity_anim.setDuration(300) # 显示动画为400ms
self.dia_hide_opacity_anim.setStartValue(1.0)
self.dia_hide_opacity_anim.setEndValue(0.0)
# 2. 位置动画从当前位置滑出到下方100px与显示动画反向
self.dia_hide_pos_anim = QPropertyAnimation(
self.system_diagnostics_dialog, b"geometry", self.system_diagnostics_dialog
)
self.dia_hide_pos_anim.setDuration(300)
self.dia_hide_pos_anim.setEasingCurve(QEasingCurve.InQuart) # 滑出曲线与显示反向
# 3. 组合动画(同时执行滑出和淡出)
self.dia_hide_anim_group = QParallelAnimationGroup(self.system_diagnostics_dialog)
self.dia_hide_anim_group.addAnimation(self.dia_hide_opacity_anim)
self.dia_hide_anim_group.addAnimation(self.dia_hide_pos_anim)
# 动画结束后强制隐藏弹窗
self.dia_hide_anim_group.finished.connect(self.system_diagnostics_dialog.hide)
def toggle_system_diagnostics_dialog(self):
"""切换系统诊断弹窗的显示/隐藏状态"""
if self.system_diagnostics_dialog.isVisible():
# 已显示 → 执行隐藏动画
self._start_diagnostics_hide_animation()
else:
# 未显示 → 计算位置并显示(触发显示动画)
self._calc_system_diagnostics_dialog_position()
self.system_diagnostics_dialog.show()
def _calc_system_diagnostics_dialog_position(self):
"""计算系统诊断弹窗位置(显示在诊断按钮上方,与中心弹窗布局一致)"""
btn = self.bottom_control_widget.diagnosis_btn # 诊断按钮
bottom_widget = self.bottom_control_widget
# 计算按钮在主窗口中的绝对位置
bottom_pos_rel_main = bottom_widget.pos() # 底部控件相对于主窗口的位置
btn_pos_rel_bottom = btn.pos() # 诊断按钮相对于底部控件的位置
btn_pos_rel_main = bottom_pos_rel_main + btn_pos_rel_bottom # 诊断按钮在主窗口中的绝对位置
# 计算弹窗坐标(显示在按钮上方,水平居中对齐)
btn_width = btn.width()
dialog_size = self.system_diagnostics_dialog.size()
# 水平方向:与按钮居中对齐
# dialog_x = btn_pos_rel_main.x() + (btn_width - dialog_size.width()) // 2
# dialog_x = btn_pos_rel_main.x() + (btn_width - dialog_size.width())
dialog_x = btn_pos_rel_main.x() # 与系统诊断按钮的左边平齐
# 垂直方向在按钮上方与按钮保持10px间距
# dialog_y = btn_pos_rel_main.y() - dialog_size.height() - 10
dialog_y = btn_pos_rel_main.y() - dialog_size.height()
# 设置弹窗位置(动画会基于此位置执行滑入效果)
self.system_diagnostics_dialog.move(dialog_x, dialog_y)
def _start_diagnostics_hide_animation(self):
"""启动系统诊断弹窗的隐藏动画(滑出+淡出)"""
current_geo = self.system_diagnostics_dialog.geometry() # 当前位置和尺寸
# 计算隐藏动画终点当前位置下方100px与显示动画起点对应
end_rect = QRect(
current_geo.x(),
current_geo.y() + 100, # 向下滑出100px
current_geo.width(),
current_geo.height()
)
# 设置动画参数并启动
self.dia_hide_pos_anim.setStartValue(current_geo)
self.dia_hide_pos_anim.setEndValue(end_rect)
self.dia_hide_anim_group.start()