From 57c452e2d345ad9db93d33b059e320ab37f22031 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 10 Jun 2026 09:12:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(ela):=20=E8=8F=9C=E5=8D=95=E5=85=A8?= =?UTF-8?q?=E6=8D=A2=20ElaMenu/ElaMenuBar(=E6=A0=B9=E6=B2=BB=E5=9C=86?= =?UTF-8?q?=E8=A7=92=E9=9C=B2=E7=9B=B4=E8=A7=92)=20+=20=E7=99=BB=E5=87=BA?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TopBar: 4 主菜单/子菜单/切换器菜单 → ElaMenu, 菜单栏 → ElaMenuBar(自绘透明圆角弹窗+随主题); 去掉 #appMenuBar 内联 QSS; Theme.cpp 删除 QMenuBar/QMenu QSS(否则 border-radius 仍露直角) - 登出: 头像改可点击 QToolButton + ElaMenu「退出登录」→ logoutRequested 信号; main 接信号 → forgetSession() 清凭证 + QProcess 重启回登录页(撤销之前的 GEOPRO_FORCE_LOGIN 补丁) --- src/app/Theme.cpp | 36 ++---------------------------------- src/app/TopBar.cpp | 42 ++++++++++++++++++++++-------------------- src/app/TopBar.hpp | 1 + src/app/main.cpp | 8 ++++++++ 4 files changed, 33 insertions(+), 54 deletions(-) diff --git a/src/app/Theme.cpp b/src/app/Theme.cpp index d9bc575..9a9a314 100644 --- a/src/app/Theme.cpp +++ b/src/app/Theme.cpp @@ -250,40 +250,8 @@ QStatusBar QLabel { padding: 0 4px; } -/* ── 菜单栏 / 菜单(按需出现时也与主题一致)────────────────── */ -QMenuBar { - background: #EDF1F7; - color: #1F2A3D; - border-bottom: 1px solid #D5DBE5; -} -QMenuBar::item { - background: transparent; - padding: 6px 12px; - border-radius: 6px; -} -QMenuBar::item:selected { - background: #DCE6F4; -} -QMenu { - background: #FFFFFF; - color: #1F2A3D; - border: 1px solid #D5DBE5; - border-radius: 8px; - padding: 6px; -} -QMenu::item { - padding: 6px 24px 6px 14px; - border-radius: 6px; -} -QMenu::item:selected { - background: #DCE9F8; - color: #1B3D67; -} -QMenu::separator { - height: 1px; - background: #E1E6EE; - margin: 6px 8px; -} +/* ── 菜单栏 / 菜单:已全部改用 ElaMenuBar/ElaMenu(自绘透明圆角弹窗+随主题), + 这里不再写 QMenuBar/QMenu 的 QSS——否则 border-radius 会让弹窗圆角露出后面的直角。 */ /* ── 下拉框(按需出现时也与主题一致)──────────────────────── */ QComboBox { diff --git a/src/app/TopBar.cpp b/src/app/TopBar.cpp index 77811c9..00f7125 100644 --- a/src/app/TopBar.cpp +++ b/src/app/TopBar.cpp @@ -16,6 +16,9 @@ #include "Glyphs.hpp" #include "Theme.hpp" +#include +#include + namespace geopro::app { namespace { @@ -51,7 +54,7 @@ QToolButton* makeIconButton(QWidget* parent, Glyph g, const QString& tip) // ── 四个菜单(结构对齐需求;叶子项当前为静态占位,后续接真实页面)── QMenu* buildViewMenu(QWidget* p) { - auto* m = new QMenu(QStringLiteral("视图"), p); + auto* m = new ElaMenu(QStringLiteral("视图"), p); m->addAction(QStringLiteral("分析视图")); m->addAction(QStringLiteral("大屏视图")); return m; @@ -59,7 +62,7 @@ QMenu* buildViewMenu(QWidget* p) QMenu* buildProjectMenu(QWidget* p) { - auto* m = new QMenu(QStringLiteral("项目管理"), p); + auto* m = new ElaMenu(QStringLiteral("项目管理"), p); m->addAction(QStringLiteral("数据视图")); auto* cfg = m->addMenu(QStringLiteral("项目配置")); cfg->addAction(QStringLiteral("基本信息")); @@ -93,7 +96,7 @@ QMenu* buildProjectMenu(QWidget* p) QMenu* buildToolsMenu(QWidget* p) { - auto* m = new QMenu(QStringLiteral("业务工具"), p); + auto* m = new ElaMenu(QStringLiteral("业务工具"), p); m->addAction(QStringLiteral("ERT 思维分析")); m->addAction(QStringLiteral("电法脚本与装置")); m->addAction(QStringLiteral("Geo 反演")); @@ -103,7 +106,7 @@ QMenu* buildToolsMenu(QWidget* p) QMenu* buildDeviceMenu(QWidget* p) { - auto* m = new QMenu(QStringLiteral("设备"), p); + auto* m = new ElaMenu(QStringLiteral("设备"), p); m->addAction(QStringLiteral("连接设备")); m->addAction(QStringLiteral("设备管理")); return m; @@ -113,16 +116,9 @@ QMenu* buildDeviceMenu(QWidget* p) QWidget* buildMenuBar(QWidget* parent) { - auto* mb = new QMenuBar(parent); + auto* mb = new ElaMenuBar(parent); mb->setObjectName(QStringLiteral("appMenuBar")); - // 自带样式(覆盖全局),加大字号/内边距,专业观感。 - geopro::app::applyThemedStyleSheet( - mb, QStringLiteral( - "#appMenuBar { background:#FFFFFF; border-bottom:1px solid #EEF1F5; padding:2px 8px; }" - "#appMenuBar::item { padding:7px 14px; border-radius:6px; font-size:%1px; color:#1F2A3D; }" - "#appMenuBar::item:selected { background:#EAF1FB; color:#2D6CB5; }" - "#appMenuBar::item:pressed { background:#DCE6F4; }") - .arg(type::kBody)); + // ElaMenuBar 自绘 Fluent 外观并自动随 ElaTheme 明暗,不再写内联 QSS。 mb->addMenu(buildViewMenu(mb)); mb->addMenu(buildProjectMenu(mb)); mb->addMenu(buildToolsMenu(mb)); @@ -169,7 +165,7 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) { wsBtn_->setPopupMode(QToolButton::InstantPopup); wsBtn_->setCursor(Qt::PointingHandCursor); wsBtn_->setText(QStringLiteral("正在加载工作空间…")); - wsBtn_->setMenu(new QMenu(wsBtn_)); + wsBtn_->setMenu(new ElaMenu(wsBtn_)); lay->addWidget(wsBtn_); lay->addSpacing(10); @@ -185,7 +181,7 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) { projBtn_->setPopupMode(QToolButton::InstantPopup); projBtn_->setCursor(Qt::PointingHandCursor); projBtn_->setText(QStringLiteral("正在加载项目…")); - projBtn_->setMenu(new QMenu(projBtn_)); + projBtn_->setMenu(new ElaMenu(projBtn_)); lay->addWidget(projBtn_); lay->addStretch(); @@ -197,11 +193,17 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) { lay->addWidget(makeDivider(this)); lay->addSpacing(12); - // 用户区(本轮静态)。 - auto* avatar = new QLabel(QStringLiteral("ZL"), this); + // 用户区:头像可点击 → 弹出菜单(退出登录)。 + auto* avatar = new QToolButton(this); avatar->setObjectName(QStringLiteral("avatar")); + avatar->setText(QStringLiteral("ZL")); avatar->setFixedSize(34, 34); - avatar->setAlignment(Qt::AlignCenter); + avatar->setCursor(Qt::PointingHandCursor); + avatar->setPopupMode(QToolButton::InstantPopup); + auto* userMenu = new ElaMenu(avatar); + QObject::connect(userMenu->addAction(QStringLiteral("退出登录")), &QAction::triggered, this, + [this] { emit logoutRequested(); }); + avatar->setMenu(userMenu); lay->addWidget(avatar); lay->addSpacing(8); @@ -219,7 +221,7 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) { } void TopBar::setWorkspaces(const std::vector& list, const QString& currentId) { - auto* menu = new QMenu(wsBtn_); + auto* menu = new ElaMenu(wsBtn_); auto* header = menu->addAction(QStringLiteral("切换空间")); header->setEnabled(false); menu->addSeparator(); @@ -250,7 +252,7 @@ void TopBar::setWorkspaces(const std::vector& list, const QStri void TopBar::setProjects(const std::vector& list, const QString& currentId, bool hasMore) { - auto* menu = new QMenu(projBtn_); + auto* menu = new ElaMenu(projBtn_); auto* header = menu->addAction(QStringLiteral("切换项目")); header->setEnabled(false); menu->addSeparator(); diff --git a/src/app/TopBar.hpp b/src/app/TopBar.hpp index b6388ae..662bed6 100644 --- a/src/app/TopBar.hpp +++ b/src/app/TopBar.hpp @@ -25,6 +25,7 @@ signals: void workspaceSwitchRequested(const QString& tenantId); void projectSwitchRequested(const QString& projectId); void allProjectsRequested(); // 点击"全部项目…" + void logoutRequested(); // 头像菜单「退出登录」 private: QToolButton* wsBtn_ = nullptr; diff --git a/src/app/main.cpp b/src/app/main.cpp index 786d983..1b5e087 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -841,6 +842,13 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re &geopro::controller::WorkbenchNavController::switchWorkspace); QObject::connect(topBar, &geopro::app::TopBar::projectSwitchRequested, &nav, &geopro::controller::WorkbenchNavController::switchProject); + // 退出登录:清除记住的凭证(QtKeychain+QSettings) → 重启应用回到登录页。 + QObject::connect(topBar, &geopro::app::TopBar::logoutRequested, &window, []() { + geopro::app::forgetSession(); + QProcess::startDetached(QCoreApplication::applicationFilePath(), + QCoreApplication::arguments().mid(1)); + qApp->quit(); + }); QObject::connect(topBar, &geopro::app::TopBar::allProjectsRequested, &window, [&projectRepo, &nav, topBar, &window]() { auto* dlg = new geopro::app::ProjectListDialog(projectRepo, &window);