系统诊断增加设备检测
This commit is contained in:
@ -8,6 +8,8 @@ from view.widgets.message_popup_widget import MessagePopupWidget
|
||||
from service.msg_recorder import MessageRecorder
|
||||
from service.msg_query_thread import MsgQueryThread
|
||||
|
||||
from service.device_monitor_thread import DeviceMonitorThread
|
||||
|
||||
"""
|
||||
控制主界面底部的所有按钮, 包括系统诊断、系统中心等的行为。
|
||||
以及 版本信息相关弹窗, 如: v1.0
|
||||
@ -20,11 +22,11 @@ class BottomControlController:
|
||||
|
||||
# 系统诊断弹窗
|
||||
self.system_diagnostics_dialog = SystemDiagnosticsDialog(self.main_window)
|
||||
self._init_system_diagnostics_dialog_hide_animations()
|
||||
self.current_diagnostics_row = 0 # 系统诊断弹窗的行号,从0开始
|
||||
self.current_diagnostics_col = 0 # 系统诊断弹窗的列号,从0开始
|
||||
|
||||
# 系统中心弹窗
|
||||
self.system_center_dialog = SystemCenterDialog(self.main_window)
|
||||
self._init_system_center_dialog_hide_animations()
|
||||
|
||||
# ===================== 消息列表相关 ====================================
|
||||
# 系统状态消息列表控件
|
||||
@ -40,6 +42,11 @@ class BottomControlController:
|
||||
self.msg_query_thread.start() # 启动线程
|
||||
# =======================================================================
|
||||
|
||||
# ===================== 设备检测(系统诊断相关) ====================================
|
||||
self.device_monitor = DeviceMonitorThread()
|
||||
self.device_monitor.start()
|
||||
# =======================================================================
|
||||
|
||||
# 绑定主界面底部按钮的信号(如:系统诊断按钮等,点击触发弹窗)
|
||||
self._bind_buttons()
|
||||
# 绑定弹窗中按钮的信号
|
||||
@ -51,20 +58,17 @@ class BottomControlController:
|
||||
# 清空当前消息列表(避免重复)
|
||||
target_widget = self.status_msg_widget if message_type == 1 else self.warning_msg_widget
|
||||
target_widget.list_widget.clear()
|
||||
# target_widget.messages.clear()
|
||||
|
||||
# 添加新消息 (第三个为 create_time, 第四个为 last_modified)
|
||||
for content, is_processed, create_time, _ in messages:
|
||||
# 从create_time中提取时分秒
|
||||
# time_part = create_time.split()[1] # 空格分隔之后的[1]为时分秒
|
||||
# 需要添加到消息列表的消息格式为 时分秒 + 消息原始内容
|
||||
# msg_list_content = f"{create_time} {content}"
|
||||
target_widget.add_message(content, is_processed = bool(is_processed), msg_time = create_time)
|
||||
|
||||
def stop_threads(self):
|
||||
"""停止当前控制器中的所有线程"""
|
||||
if hasattr(self, 'msg_query_thread') and self.msg_query_thread.isRunning():
|
||||
self.msg_query_thread.stop()
|
||||
if hasattr(self, 'device_monitor') and self.device_monitor.isRunning():
|
||||
self.device_monitor.stop_thread()
|
||||
|
||||
def _bind_buttons(self):
|
||||
# 底部系统中心按钮 → 触发弹窗显示/隐藏
|
||||
@ -78,6 +82,9 @@ class BottomControlController:
|
||||
|
||||
# 底部预警消息列表按钮 → 触发预警消息列表显示/隐藏
|
||||
self.bottom_control_widget.warning_list_btn.clicked.connect(self.toggle_system_warning_msg_list)
|
||||
|
||||
# 设备检测结果显示(底部的系统诊断按钮处显示)
|
||||
self.device_monitor.state_result.connect( self.bottom_control_widget.set_system_status, Qt.QueuedConnection)
|
||||
|
||||
def _bind_dialog_signals(self):
|
||||
"""绑定弹窗按钮的信号"""
|
||||
@ -86,45 +93,17 @@ class BottomControlController:
|
||||
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)
|
||||
# 系统诊断弹窗的信号
|
||||
self.device_monitor.check_finished.connect(self.reset_diagnostics_row_col) # 重置系统诊断的行号和列号
|
||||
self.device_monitor.connect_success.connect(self._handle_diagnostics_connect_success) # 设备正常
|
||||
self.device_monitor.connect_failed.connect(self._handle_diagnostics_connect_failed) # 设备异常
|
||||
|
||||
# ------------------- 系统中心弹窗逻辑-------------------
|
||||
def toggle_system_center_dialog(self):
|
||||
"""切换系统中心弹窗的显示/隐藏状态"""
|
||||
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()
|
||||
self.system_center_dialog.hide()
|
||||
else:
|
||||
# 未显示 → 计算位置并显示
|
||||
self._calc_system_center_dialog_position() # 每次显示都计算位置
|
||||
@ -143,7 +122,7 @@ class BottomControlController:
|
||||
# 计算弹窗坐标
|
||||
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_x = btn_pos_rel_main.x() + (btn_width - dialog_size.width()) // 2
|
||||
dialog_y = btn_pos_rel_main.y() - dialog_size.height()
|
||||
|
||||
# 设置弹窗位置
|
||||
@ -166,86 +145,121 @@ class BottomControlController:
|
||||
# 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()
|
||||
# 已显示 → 执行隐藏
|
||||
self.system_diagnostics_dialog.hide()
|
||||
else:
|
||||
# 未显示 → 计算位置并显示(触发显示动画)
|
||||
# 立即执行设备检测
|
||||
self.device_monitor.force_immediate_check()
|
||||
# 未显示 → 计算位置并显示
|
||||
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
|
||||
|
||||
btn_pos = btn.mapToGlobal(QPoint(0, 0))
|
||||
dialog_x = btn_pos.x()
|
||||
dialog_y = btn_pos.y() - self.system_diagnostics_dialog.height()
|
||||
# 计算按钮相对于主窗口的位置
|
||||
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
|
||||
|
||||
# 设置弹窗位置(动画会基于此位置执行滑入效果)
|
||||
# 计算弹窗坐标
|
||||
dialog_size = self.system_diagnostics_dialog.size()
|
||||
dialog_x = btn_pos_rel_main.x()
|
||||
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()
|
||||
def get_diagnostics_row_col(self):
|
||||
"""获取系统诊断弹窗的 行号 和 列号, 都从0开始"""
|
||||
diagnostics_row = self.current_diagnostics_row
|
||||
diagnostics_col = self.current_diagnostics_col
|
||||
self.current_diagnostics_col += 1
|
||||
if self.current_diagnostics_col == self.system_diagnostics_dialog.max_col:
|
||||
self.current_diagnostics_row += 1
|
||||
self.current_diagnostics_col = 0
|
||||
if self.current_diagnostics_row == self.system_diagnostics_dialog.max_row:
|
||||
self.current_diagnostics_row = 0
|
||||
return diagnostics_row, diagnostics_col
|
||||
|
||||
def reset_diagnostics_row_col(self):
|
||||
"""重置系统诊断弹窗的 行号 和 列号 为0"""
|
||||
self.current_diagnostics_row = 0
|
||||
self.current_diagnostics_col = 0
|
||||
|
||||
def _handle_diagnostics_connect_success(self, device_name:str, delay:int):
|
||||
"""处理系统诊断弹窗: 设备连接成功 (设备检测正常)"""
|
||||
row, col = self.get_diagnostics_row_col()
|
||||
self.system_diagnostics_dialog.set_selected_device(row, col, device_name)
|
||||
self.system_diagnostics_dialog.set_ms_value(row, col, delay)
|
||||
if delay <= self.device_monitor.warning_delay:
|
||||
self.system_diagnostics_dialog.set_circle_status(row, col, "normal")
|
||||
else:
|
||||
self.system_diagnostics_dialog.set_circle_status(row, col, "warning")
|
||||
|
||||
def _handle_diagnostics_connect_failed(self, device_name:str):
|
||||
"""处理系统诊断弹窗: 设备检测异常"""
|
||||
row, col = self.get_diagnostics_row_col()
|
||||
self.system_diagnostics_dialog.set_selected_device(row, col, device_name)
|
||||
self.system_diagnostics_dialog.set_ms_value(row, col, -1)
|
||||
self.system_diagnostics_dialog.set_circle_status(row, col, "error")
|
||||
|
||||
# ================== 系统状态消息列表: 显示系统消息 ===================
|
||||
def toggle_system_status_msg_list(self):
|
||||
"""系统状态消息按钮点击之后 显示系统消息"""
|
||||
"""切换系统状态消息弹窗的显示/隐藏状态"""
|
||||
if not self.status_msg_widget.isVisible():
|
||||
btn_pos = self.bottom_control_widget.status_msg_btn.mapToGlobal(QPoint(0, 0))
|
||||
popup_x = btn_pos.x()
|
||||
popup_y = btn_pos.y() - self.status_msg_widget.height()
|
||||
self.status_msg_widget.move(popup_x, popup_y)
|
||||
self._calc_system_status_msg_position()
|
||||
self.status_msg_widget.show()
|
||||
else:
|
||||
self.status_msg_widget.close()
|
||||
self.status_msg_widget.hide()
|
||||
|
||||
def _calc_system_status_msg_position(self):
|
||||
"""计算系统状态消息弹窗位置, 并move移动"""
|
||||
btn = self.bottom_control_widget.status_msg_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
|
||||
|
||||
# 计算弹窗坐标
|
||||
dialog_size = self.status_msg_widget.size()
|
||||
dialog_x = btn_pos_rel_main.x()
|
||||
dialog_y = btn_pos_rel_main.y() - dialog_size.height()
|
||||
|
||||
# 设置弹窗位置
|
||||
self.status_msg_widget.move(dialog_x, dialog_y)
|
||||
|
||||
# ================== 预警消息列表: 显示预警消息 ===================
|
||||
def toggle_system_warning_msg_list(self):
|
||||
"""预警消息列表按钮点击之后 显示预警消息"""
|
||||
"""切换预警消息列表弹窗的显示/隐藏状态"""
|
||||
if not self.warning_msg_widget.isVisible():
|
||||
btn_pos = self.bottom_control_widget.warning_list_btn.mapToGlobal(QPoint(0, 0))
|
||||
popup_x = btn_pos.x()
|
||||
popup_y = btn_pos.y() - self.warning_msg_widget.height()
|
||||
self.warning_msg_widget.move(popup_x, popup_y)
|
||||
self._calc_system_warning_msg_position()
|
||||
self.warning_msg_widget.show()
|
||||
else:
|
||||
self.warning_msg_widget.close()
|
||||
self.warning_msg_widget.hide()
|
||||
|
||||
def _calc_system_warning_msg_position(self):
|
||||
"""计算预警消息列表弹窗位置, 并move移动"""
|
||||
btn = self.bottom_control_widget.warning_list_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
|
||||
|
||||
# 计算弹窗坐标
|
||||
dialog_size = self.warning_msg_widget.size()
|
||||
dialog_x = btn_pos_rel_main.x()
|
||||
dialog_y = btn_pos_rel_main.y() - dialog_size.height()
|
||||
|
||||
# 设置弹窗位置
|
||||
self.warning_msg_widget.move(dialog_x, dialog_y)
|
||||
Reference in New Issue
Block a user