""" PCM_Report 看板查看器按钮模块 使用方法:在 ui_main.py 中导入并调用 add_dashboard_button() """ import subprocess import sys import os from pathlib import Path from PySide6.QtWidgets import ( QPushButton, QFileDialog, QMessageBox, QHBoxLayout, QWidget ) def get_viewer_executable(): """ 获取看板查看器的可执行文件路径 优先查找打包后的 exe,否则使用 Python 源文件 """ # 获取当前程序所在目录 if getattr(sys, 'frozen', False): # 打包后的环境 current_dir = Path(sys.executable).parent else: # 开发环境 current_dir = Path(__file__).parent # 1. 首先查找打包后的 exe(与当前程序同级目录) exe_path = current_dir / "PCM_Viewer.exe" if exe_path.exists(): return str(exe_path), True # True 表示是 exe # 2. 查找开发环境的 Python 源文件 dev_path = Path(r"F:\PyPro\PCM_Viewer\main.py") if dev_path.exists(): return str(dev_path), False # False 表示是 py 文件 # 3. 尝试相对路径(假设两个项目在同一目录下) relative_path = current_dir.parent / "PCM_Viewer" / "main.py" if relative_path.exists(): return str(relative_path), False return None, False def add_dashboard_button(window, toolbar_layout: QHBoxLayout): """ 在工具栏添加"打开看板"按钮 Args: window: MainWindow 实例 (用于日志记录和消息框) toolbar_layout: 工具栏布局 """ # 创建按钮 open_viewer_btn = QPushButton("打开看板") open_viewer_btn.setToolTip("打开看板查看器 (全屏模式)") # 绑定点击事件 def on_open_viewer(): """打开 PCM_Viewer 全屏展示""" # 选择布局文件 file_path, _ = QFileDialog.getOpenFileName( window, "选择看板布局文件", "", "JSON文件 (*.json)" ) if not file_path: return # 检查文件是否存在 if not Path(file_path).exists(): QMessageBox.warning(window, "警告", "选择的文件不存在!") return # 获取查看器可执行文件 viewer_path, is_exe = get_viewer_executable() if not viewer_path: QMessageBox.critical( window, "错误", "未找到看板查看器程序!\n" "请确保 PCM_Viewer.exe 或 main.py 存在。" ) return # 启动 PCM_Viewer 子进程 try: if is_exe: # 打包后的 exe,直接运行 cmd = [viewer_path, file_path, "--fullscreen"] else: # Python 源文件,使用 python 解释器运行 cmd = ["python", viewer_path, file_path, "--fullscreen"] # 使用 subprocess.Popen 启动独立进程 subprocess.Popen( cmd, shell=False, # 不使用 shell,更安全 stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, # 设置工作目录为查看器所在目录 cwd=os.path.dirname(viewer_path) if is_exe else None ) # 记录日志 if hasattr(window, 'logger'): window.logger.info(f"已启动看板查看器: {viewer_path} {file_path}") except Exception as e: QMessageBox.critical(window, "错误", f"启动看板失败: {str(e)}") if hasattr(window, 'logger'): window.logger.error(f"启动看板失败: {e}") open_viewer_btn.clicked.connect(on_open_viewer) # 添加到工具栏 toolbar_layout.addWidget(open_viewer_btn) return open_viewer_btn # 兼容直接复制到 ui_main.py 的函数形式 def open_dashboard_viewer(window): """ 打开 PCM_Viewer 全屏展示(可直接复制到 ui_main.py 使用) """ # 选择布局文件 file_path, _ = QFileDialog.getOpenFileName( window, "选择看板布局文件", "", "JSON文件 (*.json)" ) if not file_path: return # 检查文件是否存在 if not Path(file_path).exists(): QMessageBox.warning(window, "警告", "选择的文件不存在!") return # 获取查看器可执行文件 viewer_path, is_exe = get_viewer_executable() if not viewer_path: QMessageBox.critical( window, "错误", "未找到看板查看器程序!\n" "请确保 PCM_Viewer.exe 或 main.py 存在。" ) return # 启动 PCM_Viewer 子进程 try: if is_exe: # 打包后的 exe,直接运行 cmd = [viewer_path, file_path, "--fullscreen"] else: # Python 源文件,使用 python 解释器运行 cmd = ["python", viewer_path, file_path, "--fullscreen"] subprocess.Popen( cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=os.path.dirname(viewer_path) if is_exe else None ) if hasattr(window, 'logger'): window.logger.info(f"已启动看板查看器: {viewer_path} {file_path}") except Exception as e: QMessageBox.critical(window, "错误", f"启动看板失败: {str(e)}") if hasattr(window, 'logger'): window.logger.error(f"启动看板失败: {e}")