diff --git a/src/app/Glyphs.cpp b/src/app/Glyphs.cpp index ff901a5..edd4a20 100644 --- a/src/app/Glyphs.cpp +++ b/src/app/Glyphs.cpp @@ -158,6 +158,47 @@ QString writeChevronIcon(bool open, const QColor& color) return path; } +QString writeCheckboxIcon(bool checked, const QColor& border, const QColor& fill, const QColor& check, + const QString& tag) +{ + constexpr int px = 16; + constexpr int kScale = 3; + QPixmap pm(px * kScale, px * kScale); + pm.fill(Qt::transparent); + + QPainter p(&pm); + p.setRenderHint(QPainter::Antialiasing, true); + const double s = px * kScale; + const double inset = s * 0.14; + const QRectF box(inset, inset, s - 2 * inset, s - 2 * inset); + const double r = s * 0.14; + + if (checked) { + p.setPen(Qt::NoPen); + p.setBrush(fill); + p.drawRoundedRect(box, r, r); + QPen cpen(check, s * 0.12); + cpen.setCapStyle(Qt::RoundCap); + cpen.setJoinStyle(Qt::RoundJoin); + p.setPen(cpen); + p.drawLine(QPointF(s * 0.30, s * 0.52), QPointF(s * 0.44, s * 0.66)); + p.drawLine(QPointF(s * 0.44, s * 0.66), QPointF(s * 0.70, s * 0.34)); + } else { + QPen bpen(border, s * 0.085); + p.setPen(bpen); + p.setBrush(fill); + p.drawRoundedRect(box, r, r); + } + p.end(); + + const QString path = QDir(QDir::tempPath()) + .filePath(QStringLiteral("geopro_chk_%1_%2.png") + .arg(tag, checked ? QStringLiteral("on") + : QStringLiteral("off"))); + pm.save(path, "PNG"); + return path; +} + namespace { // 当前主题下的 chrome 图标色:取主题主文本色(暗=浅、亮=深),保证两种模式都清晰。 QColor themedIconColor() diff --git a/src/app/Glyphs.hpp b/src/app/Glyphs.hpp index 90eeaba..303208d 100644 --- a/src/app/Glyphs.hpp +++ b/src/app/Glyphs.hpp @@ -46,4 +46,9 @@ void setThemedGlyph(QAbstractButton* button, Glyph type, int px); // 配合 QTreeView::branch 背景使用,可让选中高亮不覆盖左侧缩进/箭头列且不丢箭头。 QString writeChevronIcon(bool open, const QColor& color); +// 生成清晰复选框 PNG(供 QTreeView::indicator 的 QSS `image:url(...)`): +// 未选=明显边框空心方框;选中=填充色方框 + 白色对勾。明暗各传一套色,tag 区分文件名。 +QString writeCheckboxIcon(bool checked, const QColor& border, const QColor& fill, const QColor& check, + const QString& tag); + } // namespace geopro::app diff --git a/src/app/Theme.cpp b/src/app/Theme.cpp index 6336338..4dc6774 100644 --- a/src/app/Theme.cpp +++ b/src/app/Theme.cpp @@ -75,8 +75,6 @@ QTreeWidget, QListWidget, QTreeView, QListView { } QTreeWidget::item, QListWidget::item, QTreeView::item, QListView::item { padding: 4px 8px; - border-radius: 6px; - margin: 1px 4px; } QTreeWidget::item:hover, QListWidget::item:hover, QTreeView::item:hover, QListView::item:hover { diff --git a/src/app/panels/ObjectTreePanel.cpp b/src/app/panels/ObjectTreePanel.cpp index 5263fd2..3bafc72 100644 --- a/src/app/panels/ObjectTreePanel.cpp +++ b/src/app/panels/ObjectTreePanel.cpp @@ -6,6 +6,10 @@ #include #include +#include +#include + +#include "Glyphs.hpp" #include "Theme.hpp" #include "dto/NavDto.hpp" @@ -38,6 +42,27 @@ ObjectTreePanel::ObjectTreePanel(QWidget* parent) : QWidget(parent) { tree_ = new QTreeWidget(this); tree_->setHeaderHidden(true); tree_->setIndentation(14); // 收紧缩进 + + // 清晰复选框:自绘 PNG(未选=明显边框空心框,选中=强调色底+白勾),明暗各一套、切换重绘。 + // 规避 Fusion 原生复选框在浅底下边框过淡、看不清的问题。 + auto applyCheckboxStyle = [this]() { + const bool dark = geopro::app::isDarkTheme(); + const QColor border = dark ? QColor(0x8A, 0x92, 0x9C) : QColor(0x8A, 0x93, 0xA3); + const QColor boxBg = dark ? QColor(0x2B, 0x2D, 0x30) : QColor(0xFF, 0xFF, 0xFF); + const QColor accent = eTheme->getThemeColor( + dark ? ElaThemeType::Dark : ElaThemeType::Light, ElaThemeType::PrimaryNormal); + const QString tag = dark ? QStringLiteral("d") : QStringLiteral("l"); + const QString off = geopro::app::writeCheckboxIcon(false, border, boxBg, Qt::white, tag); + const QString on = geopro::app::writeCheckboxIcon(true, accent, accent, Qt::white, tag); + tree_->setStyleSheet(QStringLiteral("QTreeView::indicator{ width:16px; height:16px; }" + "QTreeView::indicator:unchecked{ image:url(%1); }" + "QTreeView::indicator:checked{ image:url(%2); }") + .arg(off, on)); + }; + applyCheckboxStyle(); + QObject::connect(eTheme, &ElaTheme::themeModeChanged, tree_, + [applyCheckboxStyle](ElaThemeType::ThemeMode) { applyCheckboxStyle(); }); + lay->addWidget(tree_, 1); hint_ = new QLabel(QStringLiteral("正在加载对象…"), this);