407 lines
18 KiB
C++
407 lines
18 KiB
C++
|
/**
|
||
|
* @file mainwindow.cpp
|
||
|
* @author jinchao
|
||
|
* @brief 主窗口类实现
|
||
|
* @version 1.0
|
||
|
* @date 2025-02-14
|
||
|
*
|
||
|
* @copyright Copyright (c) 2025 COMAC
|
||
|
*
|
||
|
*/
|
||
|
#include "mainwindow.h"
|
||
|
#include "./ui_mainwindow.h"
|
||
|
|
||
|
#include <QHBoxLayout>
|
||
|
#include <QLabel>
|
||
|
#include <QPushButton>
|
||
|
#include <QFont>
|
||
|
#include <QButtonGroup>
|
||
|
#include <QTextEdit>
|
||
|
#include <QProcess>
|
||
|
#include <QFile>
|
||
|
#include <QMessageBox>
|
||
|
#include <QScrollArea>
|
||
|
#include <QFrame>
|
||
|
#include <QSizePolicy>
|
||
|
#include <QMouseEvent>
|
||
|
#include <QDir>
|
||
|
#include <QCoreApplication>
|
||
|
|
||
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||
|
{
|
||
|
ui->setupUi(this);
|
||
|
|
||
|
setWindowFlags(Qt::FramelessWindowHint); // 设置为无标题栏无边框
|
||
|
|
||
|
setWindowTitle("XNSim"); // 设置窗口标题
|
||
|
|
||
|
setWindowIcon(QIcon(":/icon/XNSim.png")); // 设置窗口图标
|
||
|
|
||
|
currentIndex = 0; // 初始化当前索引
|
||
|
|
||
|
// 定义各个工具的说明文本
|
||
|
XNIDLGenInfo = "Convert model interface ICD (Interface Control Document) files into IDL "
|
||
|
"(Interface Definition Language) files for DDS (Data Distribution Service) "
|
||
|
"communication in the XNSim system; Invoke the Fast-DDS Gen tool "
|
||
|
"to generate the relevant DDS communication code using the IDL files.";
|
||
|
|
||
|
XNWrapperInfo = "Create model wrapping projects and generate template code that wraps binary "
|
||
|
"data packet models into the XNSim system.";
|
||
|
|
||
|
XNEditorInfo = "Edit the runtime configurations of the XNSim system, including "
|
||
|
"configuration files for the runtime environment, models, services, "
|
||
|
"IDL files, and more.";
|
||
|
|
||
|
XNRunnerInfo = "Run and control the XNSim system.";
|
||
|
|
||
|
XNMonitorInfo = "Monitor the runtime status of the XNSim system, scheduling threads, and "
|
||
|
"models; Monitor and collect interaction data of models.";
|
||
|
|
||
|
XNSysMonitorInfo = "A tool for monitoring CPU usage.";
|
||
|
|
||
|
// 创建主窗口的中心部件
|
||
|
QWidget *centralWidget = new QWidget(this);
|
||
|
setCentralWidget(centralWidget);
|
||
|
|
||
|
// 创建主布局
|
||
|
QHBoxLayout *mainLayout = new QHBoxLayout(centralWidget);
|
||
|
mainLayout->setObjectName("mainLayout");
|
||
|
|
||
|
// 创建左侧部件和布局
|
||
|
QWidget *leftWidget = new QWidget(this);
|
||
|
QVBoxLayout *leftLayout = new QVBoxLayout(leftWidget);
|
||
|
|
||
|
// 创建开发工具按钮
|
||
|
QPushButton *developmentButton = new QPushButton("Development\nTools", this);
|
||
|
developmentButton->setCheckable(true); // 设置为可选中
|
||
|
developmentButton->setChecked(true); // 设置为默认选中
|
||
|
developmentButton->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
developmentButton->setFixedSize(120, 100); // 设置按钮大小
|
||
|
leftLayout->addWidget(developmentButton); // 添加到左侧布局
|
||
|
|
||
|
// 创建仿真工具按钮
|
||
|
QPushButton *simulationButton = new QPushButton("Simulation\nTools", this);
|
||
|
simulationButton->setCheckable(true); // 设置为可选中
|
||
|
simulationButton->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
simulationButton->setFixedSize(120, 100); // 设置按钮大小
|
||
|
leftLayout->addWidget(simulationButton); // 添加到左侧布局
|
||
|
|
||
|
// 创建监控工具按钮
|
||
|
QPushButton *monitorButton = new QPushButton("Monitor\nTools", this);
|
||
|
monitorButton->setCheckable(true); // 设置为可选中
|
||
|
monitorButton->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
monitorButton->setFixedSize(120, 100); // 设置按钮大小
|
||
|
leftLayout->addWidget(monitorButton); // 添加到左侧布局
|
||
|
|
||
|
// 创建退出按钮
|
||
|
QPushButton *exitButton = new QPushButton("Exit", this);
|
||
|
exitButton->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
exitButton->setFixedSize(120, 100); // 设置按钮大小
|
||
|
connect(exitButton, &QPushButton::clicked, this, &QMainWindow::close); // 连接点击信号
|
||
|
leftLayout->addWidget(exitButton); // 添加到左侧布局
|
||
|
|
||
|
leftLayout->addStretch(); // 添加弹性空间
|
||
|
|
||
|
// 创建图标标签
|
||
|
QLabel *iconLabel = new QLabel(this);
|
||
|
QPixmap iconPixmap(":/icon/XNSim.png"); // 设置图标
|
||
|
iconLabel->setPixmap(
|
||
|
iconPixmap.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); // 缩放图标
|
||
|
leftLayout->addWidget(iconLabel); // 添加到左侧布局
|
||
|
|
||
|
// 创建XNSim标签
|
||
|
QLabel *XNSimLabel = new QLabel("XNSim", this);
|
||
|
QFont font("Arial", 20);
|
||
|
font.setStyleStrategy(QFont::PreferAntialias); // 设置字体策略
|
||
|
font.setBold(true); // 设置字体加粗
|
||
|
XNSimLabel->setAlignment(Qt::AlignCenter); // 设置对齐方式
|
||
|
XNSimLabel->setFont(font); // 设置字体
|
||
|
leftLayout->addWidget(XNSimLabel); // 添加到左侧布局
|
||
|
|
||
|
mainLayout->addWidget(leftWidget); // 添加左侧部件到主布局
|
||
|
|
||
|
// 创建右侧部件和布局
|
||
|
QWidget *rightWidget = new QWidget(this); // 创建右侧部件
|
||
|
QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget); // 创建右侧布局
|
||
|
|
||
|
// 创建信息显示部件
|
||
|
QWidget *infoWidget = new QWidget(this); // 创建信息显示部件
|
||
|
infoWidget->setSizePolicy(QSizePolicy::Expanding,
|
||
|
QSizePolicy::Expanding); // 设置信息显示部件的大小策略
|
||
|
QVBoxLayout *infoLayout = new QVBoxLayout(infoWidget); // 创建信息显示部件的布局
|
||
|
|
||
|
// 创建XNIDLGen相关的标签和分隔线
|
||
|
QLabel *XNIDLGenLabel = new QLabel("XNIDLGen", this); // 创建XNIDLGen标签
|
||
|
XNIDLGenLabel->setFont(QFont("Arial", 16)); // 设置字体
|
||
|
infoLayout->addWidget(XNIDLGenLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
QFrame *line1 = new QFrame(this); // 创建分隔线
|
||
|
line1->setFrameShape(QFrame::HLine); // 设置分隔线形状
|
||
|
line1->setFrameShadow(QFrame::Sunken); // 设置分隔线阴影
|
||
|
infoLayout->addWidget(line1); // 添加到信息显示部件的布局
|
||
|
|
||
|
QLabel *XNIDLGenInfoLabel = new QLabel(XNIDLGenInfo, this); // 创建XNIDLGen信息标签
|
||
|
XNIDLGenInfoLabel->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
XNIDLGenInfoLabel->setWordWrap(true); // 设置自动换行
|
||
|
infoLayout->addWidget(XNIDLGenInfoLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
QLabel *XNWrapperLabel = new QLabel("XNWrapper", this); // 创建XNWrapper标签
|
||
|
XNWrapperLabel->setFont(QFont("Arial", 16)); // 设置字体
|
||
|
infoLayout->addWidget(XNWrapperLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
QFrame *line2 = new QFrame(this); // 创建分隔线
|
||
|
line2->setFrameShape(QFrame::HLine); // 设置分隔线形状
|
||
|
line2->setFrameShadow(QFrame::Sunken); // 设置分隔线阴影
|
||
|
infoLayout->addWidget(line2); // 添加到信息显示部件的布局
|
||
|
|
||
|
QLabel *XNWrapperInfoLabel = new QLabel(XNWrapperInfo, this); // 创建XNWrapper信息标签
|
||
|
XNWrapperInfoLabel->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
XNWrapperInfoLabel->setWordWrap(true); // 设置自动换行
|
||
|
infoLayout->addWidget(XNWrapperInfoLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
QLabel *XNEditorLabel = new QLabel("XNEditor", this); // 创建XNEditor标签
|
||
|
XNEditorLabel->setFont(QFont("Arial", 16)); // 设置字体
|
||
|
infoLayout->addWidget(XNEditorLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
QFrame *line3 = new QFrame(this); // 创建分隔线
|
||
|
line3->setFrameShape(QFrame::HLine); // 设置分隔线形状
|
||
|
line3->setFrameShadow(QFrame::Sunken); // 设置分隔线阴影
|
||
|
infoLayout->addWidget(line3); // 添加到信息显示部件的布局
|
||
|
|
||
|
QLabel *XNEditorInfoLabel = new QLabel(XNEditorInfo, this); // 创建XNEditor信息标签
|
||
|
XNEditorInfoLabel->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
XNEditorInfoLabel->setWordWrap(true); // 设置自动换行
|
||
|
infoLayout->addWidget(XNEditorInfoLabel); // 添加到信息显示部件的布局
|
||
|
|
||
|
infoLayout->addStretch(); // 添加弹性空间
|
||
|
|
||
|
// 创建滚动区域
|
||
|
QScrollArea *scrollArea = new QScrollArea(this); // 创建滚动区域
|
||
|
scrollArea->setWidget(infoWidget); // 设置滚动区域的部件
|
||
|
scrollArea->setWidgetResizable(true); // 设置滚动区域可调整大小
|
||
|
scrollArea->setSizePolicy(QSizePolicy::Expanding,
|
||
|
QSizePolicy::Expanding); // 设置滚动区域的大小策略
|
||
|
|
||
|
rightLayout->addWidget(scrollArea); // 添加到右侧布局
|
||
|
|
||
|
// 创建底部按钮布局
|
||
|
QHBoxLayout *buttonLayout = new QHBoxLayout(); // 创建按钮布局
|
||
|
buttonLayout->addStretch(); // 添加弹性空间
|
||
|
|
||
|
// 创建功能按钮
|
||
|
QPushButton *button1 = new QPushButton(" XNIDLGen", this); // 创建功能按钮
|
||
|
button1->setObjectName("button1"); // 设置按钮对象名称
|
||
|
button1->setFixedSize(180, 60); // 设置按钮大小
|
||
|
button1->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
buttonLayout->addWidget(button1); // 添加到按钮布局
|
||
|
button1->setIcon(QIcon(":/icon/XNIDLGen.png")); // 设置按钮图标
|
||
|
button1->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
|
||
|
QPushButton *button2 = new QPushButton(" XNWrapper", this); // 创建功能按钮
|
||
|
button2->setObjectName("button2"); // 设置按钮对象名称
|
||
|
button2->setFixedSize(180, 60); // 设置按钮大小
|
||
|
button2->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
buttonLayout->addWidget(button2); // 添加到按钮布局
|
||
|
button2->setIcon(QIcon(":/icon/XNWrapper.png")); // 设置按钮图标
|
||
|
button2->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
|
||
|
QPushButton *button3 = new QPushButton(" XNEditor", this); // 创建功能按钮
|
||
|
button3->setObjectName("button3"); // 设置按钮对象名称
|
||
|
button3->setFixedSize(180, 60); // 设置按钮大小
|
||
|
button3->setFont(QFont("Arial", 14)); // 设置字体
|
||
|
buttonLayout->addWidget(button3); // 添加到按钮布局
|
||
|
button3->setIcon(QIcon(":/icon/XNEditor.png")); // 设置按钮图标
|
||
|
button3->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
|
||
|
// 添加按钮布局到右侧布局
|
||
|
rightLayout->addLayout(buttonLayout); // 添加到右侧布局
|
||
|
|
||
|
mainLayout->addWidget(rightWidget); // 添加右侧部件到主布局
|
||
|
|
||
|
centralWidget->setLayout(mainLayout); // 设置主布局
|
||
|
|
||
|
// 连接开发工具按钮的点击信号
|
||
|
connect(developmentButton, &QPushButton::clicked, this, [=]() {
|
||
|
XNIDLGenLabel->setText("XNIDLGen"); // 设置XNIDLGen标签文本
|
||
|
XNWrapperLabel->setText("XNWrapper"); // 设置XNWrapper标签文本
|
||
|
XNEditorLabel->setText("XNEditor"); // 设置XNEditor标签文本
|
||
|
XNWrapperLabel->setVisible(true); // 显示XNWrapper标签
|
||
|
XNEditorLabel->setVisible(true); // 显示XNEditor标签
|
||
|
line2->setVisible(true); // 显示分隔线2
|
||
|
line3->setVisible(true); // 显示分隔线3
|
||
|
XNIDLGenInfoLabel->setText(XNIDLGenInfo); // 设置XNIDLGen信息文本
|
||
|
XNWrapperInfoLabel->setText(XNWrapperInfo); // 设置XNWrapper信息文本
|
||
|
XNEditorInfoLabel->setText(XNEditorInfo); // 设置XNEditor信息文本
|
||
|
XNWrapperInfoLabel->setVisible(true); // 显示XNWrapper信息标签
|
||
|
XNEditorInfoLabel->setVisible(true); // 显示XNEditor信息标签
|
||
|
button1->setText(" XNIDLGen"); // 设置按钮文本
|
||
|
button1->setVisible(true); // 显示按钮
|
||
|
button1->setIcon(QIcon(":/icon/XNIDLGen.png")); // 设置按钮图标
|
||
|
button1->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
button2->setText(" XNWrapper"); // 设置按钮文本
|
||
|
button2->setVisible(true); // 显示按钮
|
||
|
button2->setIcon(QIcon(":/icon/XNWrapper.png")); // 设置按钮图标
|
||
|
button2->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
button3->setText(" XNEditor"); // 设置按钮文本
|
||
|
button3->setVisible(true); // 显示按钮
|
||
|
button3->setIcon(QIcon(":/icon/XNEditor.png")); // 设置按钮图标
|
||
|
button3->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
developmentButton->setChecked(true); // 设置开发工具按钮选中状态
|
||
|
simulationButton->setChecked(false); // 设置仿真工具按钮选中状态
|
||
|
monitorButton->setChecked(false); // 设置监控工具按钮选中状态
|
||
|
currentIndex = 0; // 设置当前索引
|
||
|
});
|
||
|
|
||
|
// 连接仿真工具按钮的点击信号
|
||
|
connect(simulationButton, &QPushButton::clicked, this, [=]() {
|
||
|
XNIDLGenLabel->setText("XNRunner"); // 设置XNRunner标签文本
|
||
|
XNIDLGenInfoLabel->setText(XNRunnerInfo); // 设置XNRunner信息文本
|
||
|
XNWrapperLabel->setVisible(false); // 隐藏XNWrapper标签
|
||
|
XNEditorLabel->setVisible(false); // 隐藏XNEditor标签
|
||
|
line2->setVisible(false); // 隐藏分隔线2
|
||
|
line3->setVisible(false); // 隐藏分隔线3
|
||
|
XNWrapperInfoLabel->setVisible(false); // 隐藏XNWrapper信息标签
|
||
|
XNEditorInfoLabel->setVisible(false); // 隐藏XNEditor信息标签
|
||
|
button1->setText(" XNRunner"); // 设置按钮文本
|
||
|
button1->setVisible(true); // 显示按钮
|
||
|
button1->setIcon(QIcon(":/icon/XNRunner.png")); // 设置按钮图标
|
||
|
button1->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
button2->setVisible(false); // 隐藏按钮2
|
||
|
button3->setVisible(false); // 隐藏按钮3
|
||
|
developmentButton->setChecked(false); // 设置开发工具按钮选中状态
|
||
|
simulationButton->setChecked(true); // 设置仿真工具按钮选中状态
|
||
|
monitorButton->setChecked(false); // 设置监控工具按钮选中状态
|
||
|
currentIndex = 1; // 设置当前索引
|
||
|
});
|
||
|
|
||
|
// 连接监控工具按钮的点击信号
|
||
|
connect(monitorButton, &QPushButton::clicked, this, [=]() {
|
||
|
XNIDLGenLabel->setText("XNMonitor"); // 设置XNMonitor标签文本
|
||
|
XNIDLGenInfoLabel->setText(XNMonitorInfo); // 设置XNMonitor信息文本
|
||
|
XNWrapperLabel->setText("XNSysMonitor"); // 设置XNSysMonitor标签文本
|
||
|
XNWrapperInfoLabel->setText(XNSysMonitorInfo); // 设置XNSysMonitor信息文本
|
||
|
XNWrapperLabel->setVisible(true); // 显示XNSysMonitor标签
|
||
|
XNEditorLabel->setVisible(false); // 隐藏XNEditor标签
|
||
|
line2->setVisible(true); // 显示分隔线2
|
||
|
line3->setVisible(false); // 隐藏分隔线3
|
||
|
XNWrapperInfoLabel->setVisible(true); // 显示XNSysMonitor信息标签
|
||
|
XNEditorInfoLabel->setVisible(false); // 隐藏XNEditor信息标签
|
||
|
button1->setText(" XNMonitor"); // 设置按钮文本
|
||
|
button1->setVisible(true); // 显示按钮
|
||
|
button1->setIcon(QIcon(":/icon/XNMonitor.png")); // 设置按钮图标
|
||
|
button1->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
button2->setText(" XNSysMonitor"); // 设置按钮文本
|
||
|
button2->setVisible(true); // 显示按钮
|
||
|
button2->setIcon(QIcon(":/icon/XNSysMonitor.png")); // 设置按钮图标
|
||
|
button2->setIconSize(QSize(40, 40)); // 设置图标大小
|
||
|
button3->setVisible(false); // 隐藏按钮3
|
||
|
developmentButton->setChecked(false); // 设置开发工具按钮选中状态
|
||
|
simulationButton->setChecked(false); // 设置仿真工具按钮选中状态
|
||
|
monitorButton->setChecked(true); // 设置监控工具按钮选中状态
|
||
|
currentIndex = 2; // 设置当前索引
|
||
|
});
|
||
|
|
||
|
// 连接功能按钮1的点击信号
|
||
|
connect(button1, &QPushButton::clicked, this, [=]() {
|
||
|
if (currentIndex == 0) {
|
||
|
startProcess("XNIDLGen"); // 启动XNIDLGen程序
|
||
|
} else if (currentIndex == 1) {
|
||
|
startProcess("XNRunner"); // 启动XNRunner程序
|
||
|
} else if (currentIndex == 2) {
|
||
|
startProcess("XNMonitor"); // 启动XNMonitor程序
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 连接功能按钮2的点击信号
|
||
|
connect(button2, &QPushButton::clicked, this, [=]() {
|
||
|
if (currentIndex == 0) {
|
||
|
startProcess("XNWrapper"); // 启动XNWrapper程序
|
||
|
} else if (currentIndex == 2) {
|
||
|
startProcess("XNSysMonitor"); // 启动XNSysMonitor程序
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 连接功能按钮3的点击信号
|
||
|
connect(button3, &QPushButton::clicked, this, [=]() {
|
||
|
if (currentIndex == 0) {
|
||
|
startProcess("XNEditor"); // 启动XNEditor程序
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 析构函数 - 清理UI资源
|
||
|
MainWindow::~MainWindow()
|
||
|
{
|
||
|
delete ui;
|
||
|
}
|
||
|
|
||
|
// 鼠标按下事件处理函数
|
||
|
void MainWindow::mousePressEvent(QMouseEvent *event)
|
||
|
{
|
||
|
// 仅在鼠标左键按下时记录位置
|
||
|
if (event->button() == Qt::LeftButton) {
|
||
|
// 检查是否在按钮区域
|
||
|
bool isOnButton = false;
|
||
|
for (QPushButton *button : findChildren<QPushButton *>()) {
|
||
|
// 将事件坐标转换为相对于按钮父窗口的坐标
|
||
|
QPoint buttonPos = button->mapFromParent(event->pos());
|
||
|
// 检查按钮区域是否包含事件坐标
|
||
|
if (button->rect().contains(buttonPos)) {
|
||
|
isOnButton = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 如果不在按钮区域,则开始拖动窗口
|
||
|
if (!isOnButton) {
|
||
|
m_dragging = true;
|
||
|
m_dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
|
||
|
event->accept();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 鼠标移动事件处理函数
|
||
|
void MainWindow::mouseMoveEvent(QMouseEvent *event)
|
||
|
{
|
||
|
// 如果正在拖动窗口,则更新窗口位置
|
||
|
if (m_dragging && (event->buttons() & Qt::LeftButton)) {
|
||
|
move(event->globalPosition().toPoint() - m_dragPosition);
|
||
|
event->accept();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 鼠标释放事件处理函数
|
||
|
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
|
||
|
{
|
||
|
// 鼠标左键释放时结束拖动
|
||
|
if (event->button() == Qt::LeftButton) {
|
||
|
m_dragging = false;
|
||
|
event->accept();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 启动外部程序的函数
|
||
|
void MainWindow::startProcess(const QString &programName)
|
||
|
{
|
||
|
// 创建进程对象
|
||
|
QProcess *process = new QProcess(this);
|
||
|
|
||
|
// 设置工作目录为程序所在目录
|
||
|
QDir programDir(QCoreApplication::applicationDirPath());
|
||
|
process->setWorkingDirectory(programDir.absolutePath());
|
||
|
|
||
|
// 使用绝对路径启动程序
|
||
|
QString programPath = programDir.absoluteFilePath(programName);
|
||
|
|
||
|
// 检查程序是否存在
|
||
|
if (!QFile::exists(programPath)) {
|
||
|
QMessageBox::warning(this, "Program Not Found",
|
||
|
QString("%1 not found in the current directory.").arg(programName));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// 启动程序
|
||
|
process->start(programPath);
|
||
|
}
|