界面修改以及显示
This commit is contained in:
111
controller/bottom_control_controller.py
Normal file
111
controller/bottom_control_controller.py
Normal file
@ -0,0 +1,111 @@
|
||||
# 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
|
||||
|
||||
"""
|
||||
控制主界面底部的所有按钮, 包括系统诊断、系统中心等的行为。
|
||||
以及 版本信息相关弹窗, 如: 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()
|
||||
|
||||
self._bind_dialog_signals()
|
||||
|
||||
def _bind_buttons(self):
|
||||
# 底部系统中心按钮 → 触发弹窗显示/隐藏
|
||||
self.bottom_control_widget.center_btn.clicked.connect(self.toggle_system_center_dialog)
|
||||
|
||||
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):
|
||||
"""切换弹窗的显示/隐藏状态"""
|
||||
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)
|
||||
|
||||
# ------------------- 业务逻辑方法-------------------
|
||||
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):
|
||||
"""用户中心按钮的业务逻辑"""
|
||||
# print("执行用户中心逻辑:如切换用户、修改密码等")
|
||||
45
controller/camera_controller.py
Normal file
45
controller/camera_controller.py
Normal file
@ -0,0 +1,45 @@
|
||||
# controller/camera_controller.py
|
||||
from view.widgets.vibration_video_widget import VibrationVideoWidget
|
||||
from .config_loader import load_camera_config
|
||||
|
||||
class CameraController:
|
||||
def __init__(self, video_view: VibrationVideoWidget):
|
||||
self.video_view = video_view
|
||||
self._init_camera_configs()
|
||||
|
||||
def _init_camera_configs(self):
|
||||
try:
|
||||
# 加载配置
|
||||
cam1_config = load_camera_config("上位料斗")
|
||||
cam2_config = load_camera_config("下位料斗")
|
||||
cam3_config = load_camera_config("模具车")
|
||||
|
||||
# print("rtsp_url1:", cam1_config["rtsp_url"])
|
||||
# print("rtsp_url2:", cam2_config["rtsp_url"])
|
||||
# print("rtsp_url3:", cam3_config["rtsp_url"])
|
||||
|
||||
# 设置 camera_urls
|
||||
self.video_view.set_camera_urls(
|
||||
cam1_url=cam1_config["rtsp_url"],
|
||||
cam2_url=cam2_config["rtsp_url"],
|
||||
cam3_url=cam3_config["rtsp_url"]
|
||||
)
|
||||
|
||||
# 初始化视频流
|
||||
self.video_view.init_streams()
|
||||
|
||||
self._connect_signals()
|
||||
|
||||
except Exception as e:
|
||||
print(f"初始化摄像头配置失败: {e}")
|
||||
|
||||
def _connect_signals(self):
|
||||
# 流Stream的异常错误 触发 显示重连按钮
|
||||
self.video_view.stream1.error_signal.connect(lambda name, msg: self.video_view.onStreamError(name))
|
||||
self.video_view.stream2.error_signal.connect(lambda name, msg: self.video_view.onStreamError(name))
|
||||
self.video_view.stream3.error_signal.connect(lambda name, msg: self.video_view.onStreamError(name))
|
||||
|
||||
# 视频显示模组的 重连信号 连接 流Stream的重连函数
|
||||
self.video_view.cam1.reset_signal.connect(self.video_view.stream1.reset_retry)
|
||||
self.video_view.cam2.reset_signal.connect(self.video_view.stream2.reset_retry)
|
||||
self.video_view.cam3.reset_signal.connect(self.video_view.stream3.reset_retry)
|
||||
39
controller/config_loader.py
Normal file
39
controller/config_loader.py
Normal file
@ -0,0 +1,39 @@
|
||||
import configparser
|
||||
import os
|
||||
|
||||
def load_camera_config(camera_name):
|
||||
"""读取指定摄像头的配置, 并生成RTSP URL"""
|
||||
config = configparser.ConfigParser()
|
||||
# "项目根目录/config/camera_config.ini"
|
||||
config_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)), # 项目根目录
|
||||
"config",
|
||||
"camera_config.ini"
|
||||
)
|
||||
# 检查配置文件是否存在
|
||||
if not os.path.exists(config_path):
|
||||
raise FileNotFoundError(f"摄像头配置文件不存在:{config_path}")
|
||||
|
||||
config.read(config_path, encoding="utf-8")
|
||||
|
||||
if camera_name not in config.sections():
|
||||
raise ValueError(f"配置文件中未找到摄像头:{camera_name}")
|
||||
|
||||
# 读取基础配置
|
||||
ip = config.get(camera_name, "ip")
|
||||
port = config.getint(camera_name, "port")
|
||||
username = config.get(camera_name, "username")
|
||||
password = config.get(camera_name, "password")
|
||||
channel = config.get(camera_name, "channel")
|
||||
|
||||
# 生成RTSP URL
|
||||
rtsp_url = f"rtsp://{username}:{password}@{ip}:{port}/streaming/channels/{channel}"
|
||||
|
||||
return {
|
||||
"ip": ip,
|
||||
"port": port,
|
||||
"username": username,
|
||||
"password": password,
|
||||
"channel": channel,
|
||||
"rtsp_url": rtsp_url
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
from view.main_window import MainWindow
|
||||
from .camera_controller import CameraController
|
||||
from .bottom_control_controller import BottomControlController
|
||||
|
||||
class MainController:
|
||||
def __init__(self):
|
||||
@ -9,7 +11,7 @@ class MainController:
|
||||
self._initSubViews()
|
||||
|
||||
# 初始化子控制器
|
||||
# self._initSubControllers()
|
||||
self._initSubControllers()
|
||||
|
||||
|
||||
# self.__connectSignals()
|
||||
@ -17,5 +19,17 @@ class MainController:
|
||||
def showMainWindow(self):
|
||||
self.main_window.show()
|
||||
|
||||
def _initSubControllers(self):
|
||||
# 振捣视频控制
|
||||
self.camera_controller = CameraController(
|
||||
video_view=self.main_window.vibration_video
|
||||
)
|
||||
# 底部控制(按钮)控制器
|
||||
self.bottom_control_controller = BottomControlController(
|
||||
bottom_control_widget=self.main_window.bottom_control_widget,
|
||||
main_window=self.main_window
|
||||
)
|
||||
|
||||
|
||||
def _initSubViews(self):
|
||||
pass
|
||||
pass
|
||||
Reference in New Issue
Block a user