geopro/src/app/Theme.cpp

429 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Theme.hpp"
#include <QApplication>
#include <QColor>
#include <QFont>
#include <QPalette>
#include <QStyleFactory>
namespace geopro::app {
namespace {
// 全局样式表(浅色专业)。只描述外观,不含任何交互逻辑。
// 注意:刻意不重写 QCheckBox::indicator —— Fusion 一旦检测到 indicator 子控件被改写,
// 就需要自带勾选 image否则勾选态会变成空白方块。这里交给 Fusion 原生绘制,
// 它会自动采用调色板的 Highlight(#2D6CB5) 作勾选色,省去打包图片资源。
const char* kStyleSheet = R"QSS(
/* ── 基础 ───────────────────────────────────────────────── */
QWidget {
color: #1F2A3D;
}
QMainWindow, QDialog {
background: #F4F6FA;
}
QToolTip {
background: #1F2A3D;
color: #F4F6FA;
border: 1px solid #2D6CB5;
border-radius: 4px;
padding: 4px 8px;
}
/* ── 视图内工具条2D/3D、数据详情白底分段控件柔和不刺眼 ── */
QToolBar {
background: #FFFFFF;
border: none;
border-bottom: 1px solid #EAEEF4;
padding: 6px 8px;
spacing: 4px;
}
QToolBar QToolButton {
background: transparent;
color: #5A6B85;
border: none;
border-radius: 7px;
padding: 6px 14px;
font-weight: 500;
}
QToolBar QToolButton:hover {
background: #EEF3FB;
color: #1F2A3D;
}
QToolBar QToolButton:pressed {
background: #DCE9F8;
}
QToolBar QToolButton:checked {
background: #EAF1FB;
color: #2D6CB5;
font-weight: 600;
}
QToolBar QToolButton:checked:hover {
background: #DCE9F8;
}
QToolBar::separator {
background: #EAEEF4;
width: 1px;
margin: 6px 8px;
}
/* ── 树 / 列表:无边框(靠面板与留白分隔,去掉线框感)+ 充足行距 ── */
QTreeWidget, QListWidget, QTreeView, QListView {
background: #FFFFFF;
border: none;
padding: 6px;
outline: none;
}
QTreeWidget::item, QListWidget::item, QTreeView::item, QListView::item {
padding: 7px 8px;
border-radius: 6px;
margin: 1px 4px;
}
QTreeWidget::item:hover, QListWidget::item:hover,
QTreeView::item:hover, QListView::item:hover {
background: #EEF3FB;
}
QTreeWidget::item:selected, QListWidget::item:selected,
QTreeView::item:selected, QListView::item:selected {
background: #DCE9F8;
color: #1B3D67;
}
/* 注意:不要给 QTreeView::branch 设 background——一旦改写 branchQt 会停止绘制
默认的展开/折叠箭头(与 indicator 同类陷阱),父节点折叠图标会消失。 */
/* 表头(对象显示栏) */
QHeaderView::section {
background: #EDF1F7;
color: #3A475C;
border: none;
border-bottom: 1px solid #D5DBE5;
padding: 6px 8px;
font-weight: 600;
}
/* ── 标签页(数据 / 文件):现代下划线 tab无边框盒子 ──────── */
QTabWidget::pane {
border: none;
border-top: 1px solid #EAEEF4;
top: 0;
background: #FFFFFF;
}
QTabBar {
background: transparent;
}
QTabBar::tab {
background: transparent;
color: #5A6B85;
border: none;
border-bottom: 2px solid transparent;
padding: 8px 16px;
margin-right: 4px;
}
QTabBar::tab:selected {
color: #2D6CB5;
border-bottom: 2px solid #2D6CB5;
font-weight: 600;
}
QTabBar::tab:hover:!selected {
color: #1F2A3D;
}
/* ── 复选框(仅调间距/字色indicator 交给 Fusion 原生)──── */
QCheckBox {
spacing: 7px;
color: #1F2A3D;
}
QCheckBox:disabled {
color: #9AA6B6;
}
/* ── 通用按钮 / 输入(登录窗内部各自再覆盖)────────────────── */
QPushButton {
background: #FFFFFF;
color: #1F2A3D;
border: 1px solid #C2CCDA;
border-radius: 6px;
padding: 6px 14px;
}
QPushButton:hover {
background: #EEF3FB;
border-color: #2D6CB5;
}
QPushButton:pressed {
background: #DCE9F8;
}
QPushButton:default {
background: #2D6CB5;
color: #FFFFFF;
border-color: #2D6CB5;
}
QPushButton:default:hover {
background: #2862A6;
}
QPushButton:disabled {
background: #F0F2F6;
color: #9AA6B6;
border-color: #DCE0E7;
}
QLineEdit {
background: #FFFFFF;
color: #1F2A3D;
border: 1px solid #C7D2E0;
border-radius: 6px;
padding: 5px 8px;
selection-background-color: #2D6CB5;
selection-color: #FFFFFF;
}
QLineEdit:focus {
border: 1px solid #2D6CB5;
}
QLineEdit:disabled {
background: #F0F2F6;
color: #8A93A3;
}
/* ── 滚动条:纤细现代(无需图片资源)───────────────────────── */
QScrollBar:vertical {
background: transparent;
width: 12px;
margin: 2px;
}
QScrollBar::handle:vertical {
background: #C2CCDA;
border-radius: 5px;
min-height: 28px;
}
QScrollBar::handle:vertical:hover {
background: #A7B4C7;
}
QScrollBar:horizontal {
background: transparent;
height: 12px;
margin: 2px;
}
QScrollBar::handle:horizontal {
background: #C2CCDA;
border-radius: 5px;
min-width: 28px;
}
QScrollBar::handle:horizontal:hover {
background: #A7B4C7;
}
QScrollBar::add-line, QScrollBar::sub-line {
width: 0;
height: 0;
}
QScrollBar::add-page, QScrollBar::sub-page {
background: transparent;
}
/* ── 分隔条:默认近乎隐形,悬停时才显淡色(去掉灰硬条)──────── */
QSplitter::handle {
background: #EAEEF4;
}
QSplitter::handle:hover {
background: #C7D2E0;
}
ads--CDockSplitter::handle {
background: #EAEEF4;
}
ads--CDockSplitter::handle:hover {
background: #C7D2E0;
}
/* ── 状态栏:底部信息条(坐标系 / 状态指示,常驻可见)──────── */
QStatusBar {
background: #FFFFFF;
color: #5A6B85;
border-top: 1px solid #EAEEF4;
}
QStatusBar::item {
border: none;
}
QStatusBar QLabel {
color: #5A6B85;
padding: 0 4px;
}
/* ── 菜单栏 / 菜单(按需出现时也与主题一致)────────────────── */
QMenuBar {
background: #EDF1F7;
color: #1F2A3D;
border-bottom: 1px solid #D5DBE5;
}
QMenuBar::item {
background: transparent;
padding: 5px 12px;
border-radius: 6px;
}
QMenuBar::item:selected {
background: #DCE6F4;
}
QMenu {
background: #FFFFFF;
color: #1F2A3D;
border: 1px solid #D5DBE5;
border-radius: 8px;
padding: 5px;
}
QMenu::item {
padding: 6px 24px 6px 14px;
border-radius: 5px;
}
QMenu::item:selected {
background: #DCE9F8;
color: #1B3D67;
}
QMenu::separator {
height: 1px;
background: #E1E6EE;
margin: 5px 8px;
}
/* ── 下拉框(按需出现时也与主题一致)──────────────────────── */
QComboBox {
background: #FFFFFF;
color: #1F2A3D;
border: 1px solid #C2CCDA;
border-radius: 6px;
padding: 5px 10px;
min-height: 18px;
}
QComboBox:hover {
border-color: #2D6CB5;
}
QComboBox:focus {
border-color: #2D6CB5;
}
QComboBox::drop-down {
border: none;
width: 22px;
}
QComboBox QAbstractItemView {
background: #FFFFFF;
border: 1px solid #D5DBE5;
border-radius: 6px;
selection-background-color: #DCE9F8;
selection-color: #1B3D67;
outline: none;
}
/* ── 分组框(按需出现时也与主题一致)──────────────────────── */
QGroupBox {
border: 1px solid #D5DBE5;
border-radius: 8px;
margin-top: 10px;
padding-top: 6px;
font-weight: 600;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 12px;
padding: 0 4px;
color: #3A475C;
}
/* ── 进度条(长任务反馈,遵循 Doherty 阈值)──────────────────── */
QProgressBar {
background: #E6EBF3;
border: none;
border-radius: 5px;
height: 8px;
text-align: center;
color: #5A6B85;
}
QProgressBar::chunk {
background: #2D6CB5;
border-radius: 5px;
}
/* ── ADS 停靠:标题栏做成「固定面板表头」(对齐原型)──────────────
面板已锁定(无关闭/浮动/拖动),每个区只一个标签即表头:统一浅色头 +
蓝色下划线强调 + 深色加粗标题。各区一致,读起来像固定子窗口表头。 */
ads--CDockAreaWidget {
background: #F4F6FA;
}
ads--CDockAreaTitleBar {
background: #EDF1F7;
border-bottom: 1px solid #D5DBE5;
padding: 0;
}
ads--CDockWidgetTab {
background: #EDF1F7;
border: none;
border-bottom: 2px solid transparent;
padding: 7px 12px;
min-height: 22px;
}
ads--CDockWidgetTab[activeTab="true"] {
background: #EDF1F7;
border-bottom: 2px solid #2D6CB5;
}
ads--CDockWidgetTab QLabel {
color: #5A6B85;
font-weight: 600;
}
ads--CDockWidgetTab[activeTab="true"] QLabel {
color: #1F2A3D;
font-weight: 600;
}
)QSS";
// 浅色专业调色板:让标准控件在无 QSS 覆盖处也保持一致底色/选中色。
QPalette buildPalette()
{
QPalette p;
const QColor shell("#F4F6FA");
const QColor panel("#FFFFFF");
const QColor text("#1F2A3D");
const QColor mutedText("#5A6B85");
const QColor accent("#2D6CB5");
p.setColor(QPalette::Window, shell);
p.setColor(QPalette::WindowText, text);
p.setColor(QPalette::Base, panel);
p.setColor(QPalette::AlternateBase, QColor("#F0F3F8"));
p.setColor(QPalette::Text, text);
p.setColor(QPalette::Button, QColor("#EDF1F7"));
p.setColor(QPalette::ButtonText, text);
p.setColor(QPalette::ToolTipBase, QColor("#1F2A3D"));
p.setColor(QPalette::ToolTipText, shell);
p.setColor(QPalette::Highlight, accent);
p.setColor(QPalette::HighlightedText, panel);
p.setColor(QPalette::PlaceholderText, mutedText);
p.setColor(QPalette::Link, accent);
// 关键:把 Fusion 用于绘制 3D 凹凸(斜角/凹槽/分隔条阴影)的明暗角色统一压成相近浅灰,
// 立体效果即塌成平面。ADS 分隔条用 palette(dark),这样也变成一条扁平浅灰细线(无 3D
p.setColor(QPalette::Light, QColor("#FFFFFF"));
p.setColor(QPalette::Midlight, QColor("#EEF1F5"));
p.setColor(QPalette::Mid, QColor("#E1E6EE"));
p.setColor(QPalette::Dark, QColor("#D7DEE8"));
p.setColor(QPalette::Shadow, QColor("#D7DEE8"));
// 禁用态:统一灰化,避免 Fusion 默认禁用色偏暗看不清。
p.setColor(QPalette::Disabled, QPalette::Text, QColor("#9AA6B6"));
p.setColor(QPalette::Disabled, QPalette::WindowText, QColor("#9AA6B6"));
p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor("#9AA6B6"));
return p;
}
} // namespace
void applyTheme(QApplication& app)
{
// Fusion跨平台一致且对 QSS 友好Windows 原生风对部分控件会忽略样式表)。
app.setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
// 基础字体:中文界面用 微软雅黑 UI 渲染最清爽;缺失时 Qt 自动回退。
// 10pt≈13px对齐主流商用客户端基准9pt 偏小显拥挤。抗锯齿优先,观感更精致。
QFont base(QStringLiteral("Microsoft YaHei UI"), 10);
base.setStyleStrategy(QFont::PreferAntialias);
app.setFont(base);
app.setPalette(buildPalette());
app.setStyleSheet(QString::fromUtf8(kStyleSheet));
}
} // namespace geopro::app