From 9782a2b93ecb2d786913a9a5f489cdba5393e9fb Mon Sep 17 00:00:00 2001 From: gaozheng Date: Fri, 26 Jun 2026 15:41:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E5=88=A0=E9=99=A4=E5=88=87?= =?UTF-8?q?=E7=89=87/=E5=BC=82=E5=B8=B8=E5=8A=A0=E7=A1=AE=E8=AE=A4=20+=20?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=E6=8C=89=E9=92=AE=E5=85=A8=E5=B1=80=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3) 删除切片/异常前弹确认框(警告图标 + 明确「删除/取消」中文按钮 + 不可撤销提示)。 4) 弹框默认英文 OK/Cancel/Yes/No 全局中文化: - 安装 Qt 自带 zh_CN 翻译(QMessageBox/QDialogButtonBox/QFileDialog 等标准按钮);加载兼顾 dev(Qt 安装路径)与部署版(exe 旁 translations\)。 - formkit::addDialogButtons 默认按钮 QString()→「确定/取消」(不依赖翻译就位,覆盖自建对话框)。 - 打包脚本补拷 qtbase_zh_CN.qm(windeployqt --no-translations 不带)。 测试:439/439 通过 --- installer/build_installer.ps1 | 10 ++++++++++ src/app/FormKit.hpp | 8 +++++--- src/app/main.cpp | 26 ++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/installer/build_installer.ps1 b/installer/build_installer.ps1 index 55ff2d0..36a4b9b 100644 --- a/installer/build_installer.ps1 +++ b/installer/build_installer.ps1 @@ -124,6 +124,16 @@ if (-not $SkipDeploy) { } finally { if (-not $adsPreexisted) { Remove-Item $adsTmp -Force -ErrorAction SilentlyContinue } } + # 中文化:windeployqt --no-translations 不带翻译,单独拷 Qt 自带 zh_CN(QMessageBox/QFileDialog + # 等标准按钮中文化;app 启动按 exe 旁 translations\ 加载)。 + $qtZh = Join-Path $QtBin '..\translations\qtbase_zh_CN.qm' + if (Test-Path $qtZh) { + $stageTr = Join-Path $StageDir 'translations' + New-Item -ItemType Directory -Force $stageTr | Out-Null + Copy-Item $qtZh $stageTr -Force + } else { + Warn "未找到 qtbase_zh_CN.qm($qtZh)—部署版标准按钮可能仍为英文" + } } # --- 5.5 随包数据:本地样本演示数据 + PROJ 数据(exe 旁布局,运行时相对定位)------- diff --git a/src/app/FormKit.hpp b/src/app/FormKit.hpp index 5c22cec..34d6391 100644 --- a/src/app/FormKit.hpp +++ b/src/app/FormKit.hpp @@ -55,9 +55,11 @@ QVBoxLayout* dialogRoot(QDialog* dlg); // 与「数据详情 / 属性面板」同款的卡片面。返回 QFrame;其 layout() 即 QVBoxLayout,向内 addSection/addLayout。 QFrame* formCard(QWidget* parent); QVBoxLayout* cardBody(QFrame* card); // 取 formCard 的内层 QVBoxLayout(便捷器) -// 标准底部按钮栏:QDialogButtonBox(Ok|Cancel),已接 accept/reject;okText/cancelText 可定制文案。 -QDialogButtonBox* addDialogButtons(QVBoxLayout* root, QDialog* dlg, const QString& okText = QString(), - const QString& cancelText = QString()); +// 标准底部按钮栏:QDialogButtonBox(Ok|Cancel),已接 accept/reject。 +// 默认中文「确定/取消」(不依赖 Qt 翻译是否就位);调用方可覆盖(如「生成/取消」)。 +QDialogButtonBox* addDialogButtons(QVBoxLayout* root, QDialog* dlg, + const QString& okText = QStringLiteral("确定"), + const QString& cancelText = QStringLiteral("取消")); // ── 可编辑表单:§7.0 统一度量(DynamicFormEditor 与各参数对话框共用,单一真相)────── QFormLayout* makeEditForm(); // 右对齐标签 + 标准行距/列距 diff --git a/src/app/main.cpp b/src/app/main.cpp index 6bfc25b..47a8940 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -50,10 +50,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -829,9 +831,20 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re // 三维体段右键删除:切片→deleteSlice / 异常→deleteAnomaly,删后刷新树。 // 异常删除须同时 refreshAnomalies(重载异常 actor)——否则列表行没了但场景里异常仍渲染(技术债,已修)。 QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::deleteDatasetRequested, &window, - [scene3dRepo, refreshAnalysis, refreshAnomalies](const QString& dsId, - const QString& ddCode) { + [scene3dRepo, refreshAnalysis, refreshAnomalies, &window](const QString& dsId, + const QString& ddCode) { const std::string id = dsId.toStdString(); + // 删除前确认(不可撤销):明确中文「删除/取消」按钮。 + const QString what = + ddCode == QStringLiteral("dd_slice") ? QStringLiteral("切片") + : QStringLiteral("异常"); + QMessageBox box(QMessageBox::Warning, QStringLiteral("删除%1").arg(what), + QStringLiteral("确定删除该%1吗?此操作不可撤销。").arg(what), + QMessageBox::NoButton, &window); + QPushButton* del = box.addButton(QStringLiteral("删除"), QMessageBox::AcceptRole); + box.addButton(QStringLiteral("取消"), QMessageBox::RejectRole); + box.exec(); + if (box.clickedButton() != del) return; // 取消 → 不删 if (ddCode == QStringLiteral("dd_slice")) { scene3dRepo->deleteSlice( id, [refreshAnalysis]() { refreshAnalysis(); }, @@ -1978,6 +1991,15 @@ int main(int argc, char* argv[]) // (当前详情链路为同线程 DirectConnection,非严格必需,但作防御性注册,见 spec §5.1)。 qRegisterMetaType(); + // Qt 标准控件文案中文化:安装 Qt 自带 zh_CN 翻译 → QMessageBox/QDialogButtonBox/QFileDialog/ + // QColorDialog 等的 OK/Cancel/Yes/No/Save… 全局显示中文。translator 须存活至程序结束(放 main 栈)。 + QTranslator qtZhTranslator; + const QString appTr = QCoreApplication::applicationDirPath() + QStringLiteral("/translations"); + if (qtZhTranslator.load(QStringLiteral("qtbase_zh_CN"), appTr) || // 部署版(exe 旁) + qtZhTranslator.load(QStringLiteral("qtbase_zh_CN"), + QLibraryInfo::path(QLibraryInfo::TranslationsPath))) // dev(Qt 安装) + app.installTranslator(&qtZhTranslator); + // 组织/应用名:QSettings 持久化(dock 布局、登录记忆等)按此定位存储位置。 QCoreApplication::setOrganizationName(QStringLiteral("Geomative")); QCoreApplication::setApplicationName(QStringLiteral("Geopro3"));