v1.1.1: 修复编译流程 — 弹窗先行 & 按钮锁死
【交互优化】
- 编译对话框在点击按钮后立刻弹出,不再先干等再弹窗
- 对话框内分阶段展示进度:保存 → 清理 → 生成CMake → CMake配置 → 编译
- 每阶段通过 processEvents() 保持界面响应
- 编译按钮在编译期间锁死(显示🔒),关闭弹窗后自动解锁
- 关闭按钮在编译完成前禁用,防止中途关闭导致状态异常
- CMake 配置失败时也显示详细错误信息
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include <QApplication>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
@@ -76,12 +77,14 @@ void MainWindow::setupUI()
|
|||||||
debugBtn->setStyleSheet("QPushButton { background: #00838F; color: white; font-weight: bold; border: none; border-radius: 4px; padding: 6px 16px; }");
|
debugBtn->setStyleSheet("QPushButton { background: #00838F; color: white; font-weight: bold; border: none; border-radius: 4px; padding: 6px 16px; }");
|
||||||
connect(debugBtn, &QPushButton::clicked, this, &MainWindow::compileDebug);
|
connect(debugBtn, &QPushButton::clicked, this, &MainWindow::compileDebug);
|
||||||
actionLayout->addWidget(debugBtn);
|
actionLayout->addWidget(debugBtn);
|
||||||
|
this->debugBtn = debugBtn;
|
||||||
|
|
||||||
QPushButton *releaseBtn = new QPushButton("🚀 编译 Release");
|
QPushButton *releaseBtn = new QPushButton("🚀 编译 Release");
|
||||||
releaseBtn->setMinimumHeight(35);
|
releaseBtn->setMinimumHeight(35);
|
||||||
releaseBtn->setStyleSheet("QPushButton { background: #AD1457; color: white; font-weight: bold; border: none; border-radius: 4px; padding: 6px 16px; }");
|
releaseBtn->setStyleSheet("QPushButton { background: #AD1457; color: white; font-weight: bold; border: none; border-radius: 4px; padding: 6px 16px; }");
|
||||||
connect(releaseBtn, &QPushButton::clicked, this, &MainWindow::compileRelease);
|
connect(releaseBtn, &QPushButton::clicked, this, &MainWindow::compileRelease);
|
||||||
actionLayout->addWidget(releaseBtn);
|
actionLayout->addWidget(releaseBtn);
|
||||||
|
this->releaseBtn = releaseBtn;
|
||||||
|
|
||||||
actionLayout->addStretch();
|
actionLayout->addStretch();
|
||||||
|
|
||||||
@@ -782,41 +785,23 @@ void MainWindow::compileRelease()
|
|||||||
|
|
||||||
void MainWindow::compileProject(const QString &buildType)
|
void MainWindow::compileProject(const QString &buildType)
|
||||||
{
|
{
|
||||||
// 先保存工程
|
// 先校验
|
||||||
if (!saveProject()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFilePath.isEmpty()) {
|
if (currentFilePath.isEmpty()) {
|
||||||
QMessageBox::warning(this, "警告", "请先保存工程!");
|
QMessageBox::warning(this, "警告", "请先保存工程!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString projectDir = QFileInfo(currentFilePath).absolutePath();
|
QString projectDir = QFileInfo(currentFilePath).absolutePath();
|
||||||
QString buildDir = projectDir + "/build";
|
|
||||||
|
|
||||||
// 删除旧的 build 目录
|
// ★ 第一时间弹窗,让用户知道开始工作了
|
||||||
QDir buildPath(buildDir);
|
|
||||||
if (buildPath.exists()) {
|
|
||||||
buildPath.removeRecursively();
|
|
||||||
}
|
|
||||||
buildPath.mkpath(buildDir);
|
|
||||||
|
|
||||||
// 生成 CMake
|
|
||||||
QString cmakePath = projectDir + "/CMakeLists.txt";
|
|
||||||
if (!cmakeGenerator->generate(config, cmakePath)) {
|
|
||||||
QMessageBox::critical(this, "错误", "生成 CMake 失败!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建编译信息对话框
|
|
||||||
QDialog *compileDialog = new QDialog(this);
|
QDialog *compileDialog = new QDialog(this);
|
||||||
compileDialog->setWindowTitle("编译 " + buildType);
|
compileDialog->setWindowTitle("编译 " + buildType);
|
||||||
compileDialog->resize(800, 600);
|
compileDialog->resize(800, 600);
|
||||||
|
compileDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
QVBoxLayout *dialogLayout = new QVBoxLayout(compileDialog);
|
QVBoxLayout *dialogLayout = new QVBoxLayout(compileDialog);
|
||||||
|
|
||||||
QLabel *titleLabel = new QLabel("🔨 编译 " + buildType + " 中...");
|
QLabel *titleLabel = new QLabel("🔨 正在准备编译 " + buildType + "...");
|
||||||
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333;");
|
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333;");
|
||||||
dialogLayout->addWidget(titleLabel);
|
dialogLayout->addWidget(titleLabel);
|
||||||
|
|
||||||
@@ -829,16 +814,69 @@ void MainWindow::compileProject(const QString &buildType)
|
|||||||
QPushButton *closeBtn = new QPushButton("❌ 关闭");
|
QPushButton *closeBtn = new QPushButton("❌ 关闭");
|
||||||
closeBtn->setMinimumHeight(35);
|
closeBtn->setMinimumHeight(35);
|
||||||
closeBtn->setStyleSheet("QPushButton { background: #C62828; color: white; font-weight: bold; font-size: 14px; border: none; border-radius: 4px; padding: 6px 16px; }");
|
closeBtn->setStyleSheet("QPushButton { background: #C62828; color: white; font-weight: bold; font-size: 14px; border: none; border-radius: 4px; padding: 6px 16px; }");
|
||||||
|
closeBtn->setEnabled(false); // 编译未完成时不可关闭
|
||||||
dialogLayout->addWidget(closeBtn);
|
dialogLayout->addWidget(closeBtn);
|
||||||
|
|
||||||
compileDialog->show();
|
// ★ 锁死编译按钮
|
||||||
|
debugBtn->setEnabled(false);
|
||||||
|
debugBtn->setText("🔒 编译中...");
|
||||||
|
releaseBtn->setEnabled(false);
|
||||||
|
releaseBtn->setText("🔒 编译中...");
|
||||||
|
|
||||||
// 执行 cmake
|
// 弹窗关闭时解锁按钮
|
||||||
outputEdit->append("📋 正在配置 CMake...\n");
|
connect(compileDialog, &QDialog::finished, this, [this]() {
|
||||||
|
debugBtn->setEnabled(true);
|
||||||
|
debugBtn->setText("🐛 编译 Debug");
|
||||||
|
releaseBtn->setEnabled(true);
|
||||||
|
releaseBtn->setText("🚀 编译 Release");
|
||||||
|
});
|
||||||
|
|
||||||
|
compileDialog->show();
|
||||||
|
QApplication::processEvents(); // 立即渲染弹窗
|
||||||
|
|
||||||
|
// ===== 阶段 1:保存工程 =====
|
||||||
|
outputEdit->append("💾 正在保存工程配置...");
|
||||||
|
if (!saveProject()) {
|
||||||
|
outputEdit->append("❌ 保存失败!");
|
||||||
|
titleLabel->setText("❌ 保存失败");
|
||||||
|
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #f44336;");
|
||||||
|
closeBtn->setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outputEdit->append("✅ 工程已保存\n");
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// ===== 阶段 2:清理旧 build =====
|
||||||
|
QString buildDir = projectDir + "/build";
|
||||||
|
outputEdit->append("🧹 正在清理旧的构建目录...");
|
||||||
|
QDir buildPath(buildDir);
|
||||||
|
if (buildPath.exists()) {
|
||||||
|
buildPath.removeRecursively();
|
||||||
|
outputEdit->append("✅ 已删除旧 build 目录\n");
|
||||||
|
} else {
|
||||||
|
outputEdit->append("✅ build 目录不存在,跳过清理\n");
|
||||||
|
}
|
||||||
|
buildPath.mkpath(buildDir);
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// ===== 阶段 3:生成 CMakeLists.txt =====
|
||||||
|
outputEdit->append("📄 正在生成 CMakeLists.txt...");
|
||||||
|
QString cmakePath = projectDir + "/CMakeLists.txt";
|
||||||
|
if (!cmakeGenerator->generate(config, cmakePath)) {
|
||||||
|
outputEdit->append("❌ 生成 CMake 失败!");
|
||||||
|
titleLabel->setText("❌ CMake 生成失败");
|
||||||
|
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #f44336;");
|
||||||
|
closeBtn->setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outputEdit->append("✅ CMakeLists.txt 已生成\n");
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// ===== 阶段 4:CMake 配置 =====
|
||||||
|
outputEdit->append("📋 正在配置 CMake...");
|
||||||
QProcess cmakeProcess;
|
QProcess cmakeProcess;
|
||||||
cmakeProcess.setWorkingDirectory(buildDir);
|
cmakeProcess.setWorkingDirectory(buildDir);
|
||||||
|
|
||||||
// 跨平台:Windows 必须指定 MinGW Makefiles 生成器
|
|
||||||
QStringList cmakeArgs;
|
QStringList cmakeArgs;
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
cmakeArgs << "-G" << "MinGW Makefiles" << "-DCMAKE_BUILD_TYPE=" + buildType << "..";
|
cmakeArgs << "-G" << "MinGW Makefiles" << "-DCMAKE_BUILD_TYPE=" + buildType << "..";
|
||||||
@@ -848,14 +886,30 @@ void MainWindow::compileProject(const QString &buildType)
|
|||||||
cmakeProcess.start("cmake", cmakeArgs);
|
cmakeProcess.start("cmake", cmakeArgs);
|
||||||
cmakeProcess.waitForFinished(30000);
|
cmakeProcess.waitForFinished(30000);
|
||||||
|
|
||||||
outputEdit->append(cmakeProcess.readAllStandardOutput());
|
QString cmakeOutput = cmakeProcess.readAllStandardOutput();
|
||||||
|
if (!cmakeOutput.isEmpty()) {
|
||||||
|
outputEdit->append(cmakeOutput);
|
||||||
|
}
|
||||||
QString cmakeError = cmakeProcess.readAllStandardError();
|
QString cmakeError = cmakeProcess.readAllStandardError();
|
||||||
if (!cmakeError.isEmpty()) {
|
if (!cmakeError.isEmpty()) {
|
||||||
outputEdit->append("⚠️ CMake 警告/错误:\n" + cmakeError);
|
outputEdit->append("⚠️ CMake 警告/错误:\n" + cmakeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行构建(跨平台:Windows 用 mingw32-make,Linux/macOS 用 make)
|
if (cmakeProcess.exitCode() != 0) {
|
||||||
outputEdit->append("\n🔨 正在编译 " + buildType + "...\n");
|
outputEdit->append("\n❌ CMake 配置失败!错误代码:" + QString::number(cmakeProcess.exitCode()));
|
||||||
|
titleLabel->setText("❌ CMake 配置失败");
|
||||||
|
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #f44336;");
|
||||||
|
closeBtn->setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outputEdit->append("✅ CMake 配置完成\n");
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// ===== 阶段 5:编译 =====
|
||||||
|
outputEdit->append("🔨 正在编译 " + buildType + "...\n");
|
||||||
|
titleLabel->setText("🔨 编译 " + buildType + " 中...");
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
QProcess makeProcess;
|
QProcess makeProcess;
|
||||||
makeProcess.setWorkingDirectory(buildDir);
|
makeProcess.setWorkingDirectory(buildDir);
|
||||||
|
|
||||||
@@ -889,6 +943,8 @@ void MainWindow::compileProject(const QString &buildType)
|
|||||||
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #f44336;");
|
titleLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #f44336;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ★ 编译完成,允许关闭和重新编译
|
||||||
|
closeBtn->setEnabled(true);
|
||||||
connect(closeBtn, &QPushButton::clicked, compileDialog, &QDialog::accept);
|
connect(closeBtn, &QPushButton::clicked, compileDialog, &QDialog::accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ private:
|
|||||||
|
|
||||||
QPushButton *saveButton;
|
QPushButton *saveButton;
|
||||||
QPushButton *generateButton;
|
QPushButton *generateButton;
|
||||||
|
QPushButton *debugBtn;
|
||||||
|
QPushButton *releaseBtn;
|
||||||
|
|
||||||
// 配置和生成器
|
// 配置和生成器
|
||||||
ProjectConfig *config;
|
ProjectConfig *config;
|
||||||
|
|||||||
Reference in New Issue
Block a user