fix(ela): 内联 chrome 也跟随主题 — 修暗色下切换器文字看不清等

截图问题根因: TopBar/PanelHeader/3D浮层 用每控件内联 setStyleSheet(硬编码浅色 hex),
未走全局 ElaTheme 替换 → 暗色下保持浅色令牌(深字落深底→看不清; 白底面板表头等)。
新增 applyThemedStyleSheet(widget,设计稿QSS): 按 ElaTheme 角色着色 + 随明暗自动重着色。
TopBar/PanelHeader/layerPanel/layerTitle 内联样式全改走它; 补 #EEF1F5/#E6EAF1/#EAEEF5 角色。
This commit is contained in:
gaozheng 2026-06-10 08:59:59 +08:00
parent 8a82029553
commit 4a785ede88
5 changed files with 79 additions and 38 deletions

View File

@ -81,7 +81,7 @@ QWidget* buildPanelHeader(Glyph icon, const QString& title, const QVector<Header
auto* header = new QWidget();
header->setObjectName(QStringLiteral("panelHeader"));
header->setFixedHeight(kHeaderHeight);
header->setStyleSheet(headerQss());
geopro::app::applyThemedStyleSheet(header, headerQss());
auto* lay = new QHBoxLayout(header);
lay->setContentsMargins(12, 0, 8, 0);
@ -114,7 +114,7 @@ TabbedPanel buildTabbedPanel(const QVector<PanelTab>& tabs, const QVector<Header
auto* header = new QWidget(box);
header->setObjectName(QStringLiteral("panelHeader"));
header->setFixedHeight(kHeaderHeight);
header->setStyleSheet(headerQss());
geopro::app::applyThemedStyleSheet(header, headerQss());
auto* hlay = new QHBoxLayout(header);
hlay->setContentsMargins(10, 0, 8, 0);
hlay->setSpacing(2);

View File

@ -3,8 +3,10 @@
#include <QApplication>
#include <QColor>
#include <QFont>
#include <QObject>
#include <QPalette>
#include <QStyleFactory>
#include <QWidget>
#include <ElaDef.h>
#include <ElaTheme.h>
@ -407,6 +409,10 @@ const RoleMap kRoleMap[] = {
{"#E6EBF3", ElaThemeType::BasicDisable}, // 进度条底
{"#EAF1FB", ElaThemeType::BasicHover}, // 工具按钮选中底
{"#C0392B", ElaThemeType::StatusDanger}, // 危险
// 内联 chromeTopBar/PanelHeader额外用到的令牌
{"#EEF1F5", ElaThemeType::BasicBorder}, // 菜单栏底边线
{"#E6EAF1", ElaThemeType::BasicBorder}, // 面板表头底边线
{"#EAEEF5", ElaThemeType::BasicBaseDeep}, // 面板徽标底
};
QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
@ -414,15 +420,21 @@ QColor roleColor(bool dark, ElaThemeType::ThemeColor role)
return eTheme->getThemeColor(dark ? ElaThemeType::Dark : ElaThemeType::Light, role);
}
// 当前模式的全局 QSS按 kRoleMap 把设计稿色令牌换成 ElaTheme 真实颜色(明/暗同源于外壳)
QString styleSheetForMode(bool dark)
// 把一段设计稿 QSS 按 ElaTheme 当前模式着色(浅色令牌→真实角色色)。供全局与内联样式共用
QString themedQss(const QString& designQss, bool dark)
{
QString s = QString::fromUtf8(kStyleSheet);
QString s = designQss;
for (const auto& rm : kRoleMap)
s.replace(QLatin1String(rm.token), roleColor(dark, rm.role).name());
return s;
}
// 当前模式的全局 QSS。
QString styleSheetForMode(bool dark)
{
return themedQss(QString::fromUtf8(kStyleSheet), dark);
}
// 调色板同样取自 ElaTheme让无 QSS 覆盖处的标准控件也与外壳一致。
QPalette buildPalette(bool dark)
{
@ -482,4 +494,19 @@ void applyTheme(QApplication& app)
applyThemeMode(app, false);
}
bool isDarkTheme()
{
return eTheme->getThemeMode() == ElaThemeType::Dark;
}
void applyThemedStyleSheet(QWidget* w, const QString& designQss)
{
if (!w) return;
w->setStyleSheet(themedQss(designQss, isDarkTheme()));
QObject::connect(eTheme, &ElaTheme::themeModeChanged, w,
[w, designQss](ElaThemeType::ThemeMode m) {
w->setStyleSheet(themedQss(designQss, m == ElaThemeType::Dark));
});
}
} // namespace geopro::app

View File

@ -9,7 +9,10 @@
// 文字 #1F2A3D 次要文字 #5A6B85 边框 #D5DBE5 强边框 #C2CCDA
// 危险 #C0392B
#include <QString>
class QApplication;
class QWidget;
namespace geopro::app {
@ -87,4 +90,12 @@ void applyThemeMode(QApplication& app, bool dark);
// 浅色主题快捷入口(= applyThemeMode(app,false))。经典壳启动调用一次。
void applyTheme(QApplication& app);
// 当前 ElaTheme 是否暗色(供内联样式判断)。
bool isDarkTheme();
// 把一段「浅色设计稿 QSS」按当前 ElaTheme 配色着色应用到 widget并随明/暗切换自动重着色。
// 用于 TopBar/PanelHeader/浮层 等带内联 setStyleSheet 的自定义 chrome——让它们也跟随主题
// (设计稿里用浅色令牌 #1F2A3D/#FFFFFF/#2D6CB5… 书写即可,与全局 QSS 同一套角色映射)。
void applyThemedStyleSheet(QWidget* w, const QString& designQss);
} // namespace geopro::app

View File

@ -116,7 +116,8 @@ QWidget* buildMenuBar(QWidget* parent)
auto* mb = new QMenuBar(parent);
mb->setObjectName(QStringLiteral("appMenuBar"));
// 自带样式(覆盖全局),加大字号/内边距,专业观感。
mb->setStyleSheet(QStringLiteral(
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; }"
@ -134,7 +135,8 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
setFixedHeight(56);
// 字号引用 Theme 排版令牌:工作空间切换器=title(15)、头像/用户名=body·label(13)、
// 角色名=caption(12)。原 11px 角色名上调到 12去掉只差 1px 的糊层级。
setStyleSheet(QStringLiteral(
geopro::app::applyThemedStyleSheet(
this, QStringLiteral(
"#appToolBar { background:#FFFFFF; border-bottom:1px solid #E1E6EE; }"
"#topDivider { color:#E1E6EE; }"
"#wsSwitcher { color:#1F2A3D; border:none; border-radius:8px; padding:8px 12px;"

View File

@ -331,9 +331,10 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
// 仅三维视图显示;含 帘面 / 体素 勾选(体素=两交叉测线散点配准 IDW 的派生层,正确归宿)。
auto* layerPanel = new QFrame(centerWidget);
layerPanel->setFrameShape(QFrame::StyledPanel);
layerPanel->setStyleSheet(
QStringLiteral("QFrame{background:rgba(255,255,255,0.96);border:1px solid #D5DBE5;"
"border-radius:8px;} QCheckBox{padding:2px 1px;color:#1F2A3D;}"
geopro::app::applyThemedStyleSheet(
layerPanel,
QStringLiteral("QFrame{background:#FFFFFF;border:1px solid #D5DBE5;border-radius:8px;}"
"QCheckBox{padding:2px 1px;color:#1F2A3D;}"
"QCheckBox:disabled{color:#9AA6B6;}"));
auto* layerLayout = new QVBoxLayout(layerPanel);
// 浮层内边距取间距令牌:左右 lg(12)、上下 ml(10),对称(原 13/10/15/11 是手调奇数)。
@ -341,8 +342,8 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
geopro::app::space::kLg, geopro::app::space::kMl);
layerLayout->setSpacing(geopro::app::space::kSm);
auto* layerTitle = new QLabel(QStringLiteral("视图详情"));
layerTitle->setStyleSheet(QStringLiteral(
"font-weight:%1;color:#2D6CB5;border:none;background:transparent;"
geopro::app::applyThemedStyleSheet(
layerTitle, QStringLiteral("font-weight:%1;color:#2D6CB5;border:none;background:transparent;"
"padding-bottom:3px;font-size:%2px;")
.arg(geopro::app::type::kWeightSemibold)
.arg(geopro::app::type::kTitle));