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 71 additions and 2 deletions
Showing only changes of commit 934e25be54 - Show all commits

View File

@ -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()

View File

@ -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

View File

@ -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 {

View File

@ -6,6 +6,10 @@
#include <QTreeWidgetItem>
#include <QVBoxLayout>
#include <ElaDef.h>
#include <ElaTheme.h>
#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);