182 lines
5.6 KiB
Python
182 lines
5.6 KiB
Python
"""
|
||
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}")
|