refactor/pure-qt-ui #3

Merged
gaozheng merged 56 commits from refactor/pure-qt-ui into main 2026-06-10 18:41:53 +08:00
4 changed files with 24 additions and 16 deletions
Showing only changes of commit d1be0567de - Show all commits

View File

@ -11,6 +11,7 @@
#include <QPixmap> #include <QPixmap>
#include <QPointF> #include <QPointF>
#include <QRectF> #include <QRectF>
#include <QSize>
#include <QString> #include <QString>
#include <QSvgRenderer> #include <QSvgRenderer>
@ -98,7 +99,7 @@ QString svgPathFor(Glyph t)
} // namespace } // namespace
QIcon makeGlyph(Glyph type, const QColor& color, int px) QIcon makeGlyph(Glyph type, const QColor& color, int px, int padRight)
{ {
const QString svg = const QString svg =
QStringLiteral("<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' " QStringLiteral("<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' "
@ -110,12 +111,13 @@ QIcon makeGlyph(Glyph type, const QColor& color, int px)
// 以 3x 超采样渲染再设 devicePixelRatio保证在任意缩放/DPI 下都清晰。 // 以 3x 超采样渲染再设 devicePixelRatio保证在任意缩放/DPI 下都清晰。
constexpr qreal kSuper = 3.0; constexpr qreal kSuper = 3.0;
const int dim = qRound(px * kSuper); const int dim = qRound(px * kSuper); // 图标本体边长(方形)
QImage img(dim, dim, QImage::Format_ARGB32_Premultiplied); const int dimW = qRound((px + padRight) * kSuper); // 含右透明内边距的画布宽
QImage img(dimW, dim, QImage::Format_ARGB32_Premultiplied);
img.fill(Qt::transparent); img.fill(Qt::transparent);
QPainter p(&img); QPainter p(&img);
p.setRenderHint(QPainter::Antialiasing, true); p.setRenderHint(QPainter::Antialiasing, true);
renderer.render(&p, QRectF(0, 0, dim, dim)); renderer.render(&p, QRectF(0, 0, dim, dim)); // 图标居左方形渲染,右侧 padRight 留透明
p.end(); p.end();
QPixmap pm = QPixmap::fromImage(img); QPixmap pm = QPixmap::fromImage(img);
@ -214,10 +216,13 @@ void setThemedGlyph(QLabel* label, Glyph type, int px)
QObject::connect(&ThemeManager::instance(), &ThemeManager::changed, label, [apply]() { apply(); }); QObject::connect(&ThemeManager::instance(), &ThemeManager::changed, label, [apply]() { apply(); });
} }
void setThemedGlyph(QAbstractButton* button, Glyph type, int px) void setThemedGlyph(QAbstractButton* button, Glyph type, int px, int padRight)
{ {
if (!button) return; if (!button) return;
auto apply = [button, type, px]() { button->setIcon(makeGlyph(type, themedIconColor(), px)); }; auto apply = [button, type, px, padRight]() {
button->setIcon(makeGlyph(type, themedIconColor(), px, padRight));
if (padRight > 0) button->setIconSize(QSize(px + padRight, px)); // 含右内边距,文字被右推
};
apply(); apply();
QObject::connect(&ThemeManager::instance(), &ThemeManager::changed, button, [apply]() { apply(); }); QObject::connect(&ThemeManager::instance(), &ThemeManager::changed, button, [apply]() { apply(); });
} }

View File

@ -34,13 +34,19 @@ enum class Glyph {
Gear, // 设置(齿轮) Gear, // 设置(齿轮)
}; };
// 生成指定颜色、像素尺寸的图标(默认 16px内部按 2x 绘制保证清晰)。 // 「图标+文字」按钮的图标→文字间距补丁Fusion 内置约 4px本值补到规范 §6.7 的 6px。
QIcon makeGlyph(Glyph type, const QColor& color, int px = 16); // 做法把图标渲染进“px 宽图标 + padRight 透明右边距”的画布,文字被这段透明区右推。
inline constexpr int kGlyphTextGapPad = 2;
// 随 ElaTheme 明暗自动着色的 glyph取主题文本色暗色用浅色、亮色用深色主题切换时自动重绘。 // 生成指定颜色、像素尺寸的图标(默认 16px内部按 3x 绘制保证清晰)。
// padRight>0 时图标画布右侧留透明内边距(用于「图标+文字」按钮统一间距),图标本体仍为 px×px 居左。
QIcon makeGlyph(Glyph type, const QColor& color, int px = 16, int padRight = 0);
// 随主题明暗自动着色的 glyph取主题文本色暗色用浅色、亮色用深色主题切换时自动重绘。
// 用于面板表头/页签等 chrome 图标,避免固定色在暗色下看不清。 // 用于面板表头/页签等 chrome 图标,避免固定色在暗色下看不清。
// 按钮版的 padRight见 kGlyphTextGapPad>0 时本函数同时把 iconSize 设为 (px+padRight)×px。
void setThemedGlyph(QLabel* label, Glyph type, int px); void setThemedGlyph(QLabel* label, Glyph type, int px);
void setThemedGlyph(QAbstractButton* button, Glyph type, int px); void setThemedGlyph(QAbstractButton* button, Glyph type, int px, int padRight = 0);
// 生成树展开/折叠箭头 PNG 到临时目录,返回文件路径(供树的 QSS `image: url(...)` 引用)。 // 生成树展开/折叠箭头 PNG 到临时目录,返回文件路径(供树的 QSS `image: url(...)` 引用)。
// 配合 QTreeView::branch 背景使用,可让选中高亮不覆盖左侧缩进/箭头列且不丢箭头。 // 配合 QTreeView::branch 背景使用,可让选中高亮不覆盖左侧缩进/箭头列且不丢箭头。

View File

@ -131,8 +131,7 @@ TabbedPanel buildTabbedPanel(const QVector<PanelTab>& tabs, const QVector<Header
auto* btn = new QToolButton(header); // 页签与工具条统一: QToolButton + 强调色下划线 QSS auto* btn = new QToolButton(header); // 页签与工具条统一: QToolButton + 强调色下划线 QSS
btn->setObjectName(QStringLiteral("tabBtn")); btn->setObjectName(QStringLiteral("tabBtn"));
btn->setText(t.title); btn->setText(t.title);
setThemedGlyph(btn, t.icon, kTabIcon); // 随主题着色 setThemedGlyph(btn, t.icon, kTabIcon, kGlyphTextGapPad); // 随主题着色 + 图标→文字6px(§6.7)
btn->setIconSize(QSize(kTabIcon, kTabIcon));
btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
btn->setCheckable(true); btn->setCheckable(true);
btn->setCursor(Qt::PointingHandCursor); btn->setCursor(Qt::PointingHandCursor);

View File

@ -197,8 +197,7 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
// 工作空间切换器QToolButton + 主题化 QSS下拉箭头用高清 chevron menu-indicator数据驱动 // 工作空间切换器QToolButton + 主题化 QSS下拉箭头用高清 chevron menu-indicator数据驱动
wsBtn_ = new QToolButton(this); wsBtn_ = new QToolButton(this);
wsBtn_->setObjectName(QStringLiteral("wsSwitcher")); wsBtn_->setObjectName(QStringLiteral("wsSwitcher"));
setThemedGlyph(wsBtn_, Glyph::Workspace, kWorkspaceIcon); // 中性主题色(蓝只留给选中/激活) setThemedGlyph(wsBtn_, Glyph::Workspace, kWorkspaceIcon, kGlyphTextGapPad); // 图标→文字6px(§6.7)
wsBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
wsBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); wsBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
wsBtn_->setPopupMode(QToolButton::InstantPopup); wsBtn_->setPopupMode(QToolButton::InstantPopup);
wsBtn_->setCursor(Qt::PointingHandCursor); wsBtn_->setCursor(Qt::PointingHandCursor);
@ -213,8 +212,7 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
// 项目切换器QToolButton + 主题化 QSS数据驱动 // 项目切换器QToolButton + 主题化 QSS数据驱动
projBtn_ = new QToolButton(this); projBtn_ = new QToolButton(this);
projBtn_->setObjectName(QStringLiteral("wsSwitcher")); projBtn_->setObjectName(QStringLiteral("wsSwitcher"));
setThemedGlyph(projBtn_, Glyph::Folder, kWorkspaceIcon); // 中性主题色 setThemedGlyph(projBtn_, Glyph::Folder, kWorkspaceIcon, kGlyphTextGapPad); // 中性主题色 + 图标→文字6px
projBtn_->setIconSize(QSize(kWorkspaceIcon, kWorkspaceIcon));
projBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); projBtn_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
projBtn_->setPopupMode(QToolButton::InstantPopup); projBtn_->setPopupMode(QToolButton::InstantPopup);
projBtn_->setCursor(Qt::PointingHandCursor); projBtn_->setCursor(Qt::PointingHandCursor);