fix(ela): 工具条选中态 + 切换器箭头改用 QToolButton+主题QSS(清晰可控)

ElaToolButton 硬限制: 选中态只画极淡 BasicHover(看不清)、展开箭头不可靠、且自绘无法被 QSS 覆盖。
故交互态强的这两类退回 QToolButton + applyThemedStyleSheet(用统一强调色):
- 视图/详情工具条(2D/3D, 原数据/网格数据, 显示异常/电极/等值线): 选中 = 强调色文字 + 2px 强调色下划线,
  明暗都清晰可辨
- 切换器: QToolButton + 文字'▾'(清晰, 不再是 ElaToolButton 那个发糙/消失的箭头) + 悬停底
其余(菜单/列表/树/表单/图标按钮)仍 Ela。强调色已全局统一为品牌蓝
This commit is contained in:
gaozheng 2026-06-10 11:39:20 +08:00
parent ec428ccaca
commit 107fed8182
3 changed files with 40 additions and 18 deletions

View File

@ -138,6 +138,9 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
"#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }" "#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }"
"#topDivider { color:#E1E6EE; }" "#topDivider { color:#E1E6EE; }"
"QToolButton::menu-indicator { image:none; }" "QToolButton::menu-indicator { image:none; }"
"#wsSwitcher { color:#1F2A3D; border:none; border-radius:8px; padding:8px 12px;"
" font-size:%6px; font-weight:%4; }"
"#wsSwitcher:hover { background:#EEF3FB; }"
"#avatar { background:#2D6CB5; color:white; border-radius:17px; font-weight:%2;" "#avatar { background:#2D6CB5; color:white; border-radius:17px; font-weight:%2;"
" font-size:%1px; }" " font-size:%1px; }"
"#userName { color:#1F2A3D; font-size:%3px; font-weight:%4; }" "#userName { color:#1F2A3D; font-size:%3px; font-weight:%4; }"
@ -146,14 +149,15 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
.arg(type::kWeightBold) .arg(type::kWeightBold)
.arg(type::kLabel) .arg(type::kLabel)
.arg(type::kWeightSemibold) .arg(type::kWeightSemibold)
.arg(type::kCaption)); .arg(type::kCaption)
.arg(type::kTitle));
auto* lay = new QHBoxLayout(this); auto* lay = new QHBoxLayout(this);
lay->setContentsMargins(14, 0, 14, 0); lay->setContentsMargins(14, 0, 14, 0);
lay->setSpacing(0); lay->setSpacing(0);
// 工作空间切换器(Fluent ElaToolButton数据驱动初始占位文本待 setWorkspaces 填充)。 // 工作空间切换器(QToolButton + 主题化 QSS下拉箭头用文字"▾"保证清晰;数据驱动)。
wsBtn_ = new ElaToolButton(this); wsBtn_ = new QToolButton(this);
wsBtn_->setObjectName(QStringLiteral("wsSwitcher")); wsBtn_->setObjectName(QStringLiteral("wsSwitcher"));
setThemedGlyph(wsBtn_, Glyph::Workspace, kWorkspaceIcon); // 中性主题色(蓝只留给选中/激活) setThemedGlyph(wsBtn_, Glyph::Workspace, kWorkspaceIcon); // 中性主题色(蓝只留给选中/激活)
wsBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon)); wsBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
@ -168,8 +172,8 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
lay->addWidget(makeDivider(this)); lay->addWidget(makeDivider(this));
lay->addSpacing(10); lay->addSpacing(10);
// 项目切换器(Fluent ElaToolButton;数据驱动)。 // 项目切换器(QToolButton + 主题化 QSS;数据驱动)。
projBtn_ = new ElaToolButton(this); projBtn_ = new QToolButton(this);
projBtn_->setObjectName(QStringLiteral("wsSwitcher")); projBtn_->setObjectName(QStringLiteral("wsSwitcher"));
setThemedGlyph(projBtn_, Glyph::Folder, kWorkspaceIcon); // 中性主题色 setThemedGlyph(projBtn_, Glyph::Folder, kWorkspaceIcon); // 中性主题色
projBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon)); projBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
@ -233,7 +237,7 @@ void TopBar::setWorkspaces(const std::vector<data::Workspace>& list, const QStri
group->addAction(a); group->addAction(a);
if (id == currentId) currentName = name; if (id == currentId) currentName = name;
QObject::connect(a, &QAction::triggered, this, [this, id, name]() { QObject::connect(a, &QAction::triggered, this, [this, id, name]() {
wsBtn_->setText(name); // 立即反馈(下拉箭头由 ElaToolButton 自绘) wsBtn_->setText(name + QStringLiteral("")); // 立即反馈
emit workspaceSwitchRequested(id); emit workspaceSwitchRequested(id);
}); });
} }
@ -242,7 +246,8 @@ void TopBar::setWorkspaces(const std::vector<data::Workspace>& list, const QStri
none->setEnabled(false); none->setEnabled(false);
} }
wsBtn_->setMenu(menu); wsBtn_->setMenu(menu);
wsBtn_->setText(currentName.isEmpty() ? QStringLiteral("选择空间") : currentName); wsBtn_->setText((currentName.isEmpty() ? QStringLiteral("选择空间") : currentName) +
QStringLiteral(""));
} }
void TopBar::setProjects(const std::vector<data::ProjectSummary>& list, const QString& currentId, void TopBar::setProjects(const std::vector<data::ProjectSummary>& list, const QString& currentId,
@ -263,7 +268,7 @@ void TopBar::setProjects(const std::vector<data::ProjectSummary>& list, const QS
group->addAction(a); group->addAction(a);
if (id == currentId) currentName = name; if (id == currentId) currentName = name;
QObject::connect(a, &QAction::triggered, this, [this, id, name]() { QObject::connect(a, &QAction::triggered, this, [this, id, name]() {
projBtn_->setText(name); projBtn_->setText(name + QStringLiteral(""));
emit projectSwitchRequested(id); emit projectSwitchRequested(id);
}); });
} }
@ -277,11 +282,12 @@ void TopBar::setProjects(const std::vector<data::ProjectSummary>& list, const QS
QObject::connect(all, &QAction::triggered, this, [this]() { emit allProjectsRequested(); }); QObject::connect(all, &QAction::triggered, this, [this]() { emit allProjectsRequested(); });
} }
projBtn_->setMenu(menu); projBtn_->setMenu(menu);
projBtn_->setText(currentName.isEmpty() ? QStringLiteral("选择项目") : currentName); projBtn_->setText((currentName.isEmpty() ? QStringLiteral("选择项目") : currentName) +
QStringLiteral(""));
} }
void TopBar::setProjectButtonText(const QString& name) { void TopBar::setProjectButtonText(const QString& name) {
projBtn_->setText(name); projBtn_->setText(name + QStringLiteral(""));
} }
} // namespace geopro::app } // namespace geopro::app

View File

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include "repo/RepoTypes.hpp" #include "repo/RepoTypes.hpp"
class ElaToolButton; class QToolButton;
namespace geopro::app { namespace geopro::app {
@ -28,8 +28,8 @@ signals:
void logoutRequested(); // 头像菜单「退出登录」 void logoutRequested(); // 头像菜单「退出登录」
private: private:
ElaToolButton* wsBtn_ = nullptr; QToolButton* wsBtn_ = nullptr;
ElaToolButton* projBtn_ = nullptr; QToolButton* projBtn_ = nullptr;
}; };
} // namespace geopro::app } // namespace geopro::app

View File

@ -39,6 +39,7 @@
#include <QModelIndex> #include <QModelIndex>
#include <QStandardItem> #include <QStandardItem>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QToolButton>
#include <QKeySequence> #include <QKeySequence>
#include <QProcess> #include <QProcess>
#include <QSettings> #include <QSettings>
@ -327,17 +328,29 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
centerLayout->setContentsMargins(0, 0, 0, 0); centerLayout->setContentsMargins(0, 0, 0, 0);
centerLayout->setSpacing(0); centerLayout->setSpacing(0);
// 工具条:「二维地图/三维视图」两个互斥可勾选按钮(Fluent ElaToolButton)。默认二维地图。 // 分段工具条按钮样式QToolButton + 主题化 QSS选中=强调色文字 + 强调色下划线,明暗都清晰。
// ElaToolButton 选中只画极淡 BasicHover、且不可经 QSS 改,故这类需清晰选中态的用 QToolButton。
const QString kBarBtnQss =
QStringLiteral(
"QToolButton{ border:none; border-radius:6px; padding:6px 12px; color:#1F2A3D;"
" font-size:%1px; }"
"QToolButton:hover{ background:#EEF3FB; }"
"QToolButton:checked{ color:#2D6CB5; font-weight:%2;"
" border-bottom:2px solid #2D6CB5; }")
.arg(geopro::app::type::kBody)
.arg(geopro::app::type::kWeightSemibold);
// 工具条:「二维地图/三维视图」两个互斥可勾选按钮。默认二维地图。
auto* viewToolBar = new QWidget(); auto* viewToolBar = new QWidget();
auto* viewBarLay = new QHBoxLayout(viewToolBar); auto* viewBarLay = new QHBoxLayout(viewToolBar);
viewBarLay->setContentsMargins(8, 6, 8, 6); viewBarLay->setContentsMargins(8, 6, 8, 6);
viewBarLay->setSpacing(6); viewBarLay->setSpacing(6);
auto* viewGroup = new QButtonGroup(viewToolBar); auto* viewGroup = new QButtonGroup(viewToolBar);
viewGroup->setExclusive(true); viewGroup->setExclusive(true);
auto* act2D = new ElaToolButton(viewToolBar); auto* act2D = new QToolButton(viewToolBar);
act2D->setText(QStringLiteral("二维地图")); act2D->setText(QStringLiteral("二维地图"));
act2D->setCheckable(true); act2D->setCheckable(true);
auto* act3D = new ElaToolButton(viewToolBar); auto* act3D = new QToolButton(viewToolBar);
act3D->setText(QStringLiteral("三维视图")); act3D->setText(QStringLiteral("三维视图"));
act3D->setCheckable(true); act3D->setCheckable(true);
viewGroup->addButton(act2D); viewGroup->addButton(act2D);
@ -346,6 +359,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
viewBarLay->addWidget(act3D); viewBarLay->addWidget(act3D);
viewBarLay->addStretch(); viewBarLay->addStretch();
act2D->setChecked(true); // 默认二维地图 act2D->setChecked(true); // 默认二维地图
geopro::app::applyThemedStyleSheet(viewToolBar, kBarBtnQss);
centerLayout->addWidget(viewToolBar); centerLayout->addWidget(viewToolBar);
centerLayout->addWidget(vtkWidget, 1); centerLayout->addWidget(vtkWidget, 1);
@ -473,13 +487,14 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
detailLayout->setContentsMargins(0, 0, 0, 0); detailLayout->setContentsMargins(0, 0, 0, 0);
detailLayout->setSpacing(0); detailLayout->setSpacing(0);
// 工具条对齐原型:「原数据 | 网格数据」互斥 +「显示异常/电极/等值线」开关Fluent ElaToolButton // 工具条对齐原型:「原数据 | 网格数据」互斥 +「显示异常/电极/等值线」开关。
// QToolButton + 主题化 QSS选中=强调色文字+下划线,明暗都清晰)。
auto* detailToolBar = new QWidget(); auto* detailToolBar = new QWidget();
auto* detailBarLay = new QHBoxLayout(detailToolBar); auto* detailBarLay = new QHBoxLayout(detailToolBar);
detailBarLay->setContentsMargins(8, 6, 8, 6); detailBarLay->setContentsMargins(8, 6, 8, 6);
detailBarLay->setSpacing(6); detailBarLay->setSpacing(6);
auto makeBarBtn = [detailToolBar](const QString& text, bool checkable) { auto makeBarBtn = [detailToolBar](const QString& text, bool checkable) {
auto* b = new ElaToolButton(detailToolBar); auto* b = new QToolButton(detailToolBar);
b->setText(text); b->setText(text);
b->setCheckable(checkable); b->setCheckable(checkable);
return b; return b;
@ -509,6 +524,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
detailBarLay->addWidget(actShowElectrodes); detailBarLay->addWidget(actShowElectrodes);
detailBarLay->addWidget(actShowContour); detailBarLay->addWidget(actShowContour);
detailBarLay->addStretch(); detailBarLay->addStretch();
geopro::app::applyThemedStyleSheet(detailToolBar, kBarBtnQss);
detailLayout->addWidget(detailToolBar); detailLayout->addWidget(detailToolBar);
detailLayout->addWidget(detailWidget, 1); detailLayout->addWidget(detailWidget, 1);