fix(ui): 栏位勾选增量保留 + tab去箭头 + 缩进 + 滑块跳位 + 清日志警告
- 栏位状态增量(最关键):CategorySection::rebuildList 记住已勾选 ds、重建后复原;之前每次刷新 (勾选对象/建体/存切片/建异常都触发)清空全部勾选→渲染被重置。复原后 emitChecked 上抛同集, 控制器据 diff 增量保留已渲染图元 - #1 tab 左右滚动箭头:上轮宽度算法没扣 padding 致溢出。扣开销(~42)稍欠宽 + setUsesScrollButtons(false) 兜底 - #6 缩进:容器文本左缘对齐子级复选框列起点(pad 12,非整列36),「容器→带框子级」缩进=树级(14), 与「带框→带框」一致,且名称仍紧邻展开图标(无 #2 大留白) - 5.5 滑块点轨道跳位:ClickJumpSlider 用 QStyle::sliderValueFromPosition 点哪跳哪(点手柄正常拖动) - 日志 201× QFont pointSize<=0(-1) 警告:ObjectRowDelegate 去掉多余 setPointSizeF(-1)(setPixelSize 直接生效) 构建:app 链接通过
This commit is contained in:
parent
63fe99dba5
commit
09a48d846b
|
|
@ -7,14 +7,43 @@
|
|||
#include <QDoubleSpinBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QStyle>
|
||||
#include <QStyleOptionSlider>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Theme.hpp"
|
||||
|
||||
namespace geopro::app {
|
||||
|
||||
namespace {
|
||||
// 点击轨道直接定位到点击处(默认 QSlider 点轨道只按 pageStep 步进;用户要求点哪跳哪)。
|
||||
class ClickJumpSlider : public QSlider {
|
||||
public:
|
||||
using QSlider::QSlider;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* e) override {
|
||||
if (e->button() == Qt::LeftButton && orientation() == Qt::Horizontal) {
|
||||
QStyleOptionSlider opt;
|
||||
initStyleOption(&opt);
|
||||
const QRect handle =
|
||||
style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
|
||||
if (!handle.contains(e->pos())) { // 点在轨道(非手柄) → 跳到点击位置
|
||||
const int span = width() - handle.width();
|
||||
const int x = e->pos().x() - handle.width() / 2;
|
||||
setValue(QStyle::sliderValueFromPosition(minimum(), maximum(), x, span));
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
QSlider::mousePressEvent(e); // 点手柄 → 正常拖动
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
AxesSettingsPanel::AxesSettingsPanel(QWidget* parent) : QFrame(parent) {
|
||||
setFrameShape(QFrame::StyledPanel);
|
||||
applyTokenizedStyleSheet(
|
||||
|
|
@ -64,7 +93,7 @@ AxesSettingsPanel::AxesSettingsPanel(QWidget* parent) : QFrame(parent) {
|
|||
auto* scaleLbl = new QLabel(QStringLiteral("放大系数"), this);
|
||||
scaleLbl->setStyleSheet(QStringLiteral("border:none;"));
|
||||
scaleRow->addWidget(scaleLbl);
|
||||
scaleSlider_ = new QSlider(Qt::Horizontal, this);
|
||||
scaleSlider_ = new ClickJumpSlider(Qt::Horizontal, this);
|
||||
scaleSlider_->setMinimum(1);
|
||||
scaleSlider_->setMaximum(10);
|
||||
scaleSlider_->setValue(1);
|
||||
|
|
|
|||
|
|
@ -84,10 +84,11 @@ public:
|
|||
// 可勾选项:左侧画复选框(用当前 style 的指示器),文本整体右移。容器节点(项目/GS/TM)不画
|
||||
// 复选框、名称紧跟展开图标(左留白小,与对象树容器一致;勿为对齐子级而预留空复选框列,
|
||||
// 否则容器名与展开图标间出现大段空白,见用户 #2 反馈)。
|
||||
const int box = 16;
|
||||
int textLeftPad = 6;
|
||||
const bool checkable = (idx.flags() & Qt::ItemIsUserCheckable);
|
||||
const bool isContainer = idx.data(kDsDdCodeRole).toString() == QStringLiteral("container");
|
||||
if (checkable) {
|
||||
const int box = 16;
|
||||
QRect checkRect(r.left() + 12, r.top() + (r.height() - box) / 2, box, box);
|
||||
const auto cs = static_cast<Qt::CheckState>(idx.data(Qt::CheckStateRole).toInt());
|
||||
QStyleOptionViewItem o(opt);
|
||||
|
|
@ -98,6 +99,11 @@ public:
|
|||
QStyle* st = w ? w->style() : QApplication::style();
|
||||
st->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &o, p, w);
|
||||
textLeftPad = 12 + box + 8; // 复选框右侧留白后再放文本
|
||||
} else if (isContainer) {
|
||||
// 容器文本左缘对齐子级复选框的左缘(r.left()+12)——使「容器→带框子级」的视觉缩进 = 一个树级
|
||||
// (14px),与「带框父→带框子」一致,消除带框子级相对容器缩进过大(用户 #6)。只 +12(非整列宽),
|
||||
// 故名称仍紧邻展开图标、无 #2 的大留白。
|
||||
textLeftPad = 12;
|
||||
}
|
||||
|
||||
QString title = disp, meta;
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ public:
|
|||
const int count = idx.data(kRoleChildCount).toInt();
|
||||
if (count > 0) {
|
||||
QFont f = opt.font;
|
||||
f.setPointSizeF(-1);
|
||||
f.setPixelSize(scaledPx(type::kCaption));
|
||||
f.setPixelSize(scaledPx(type::kCaption)); // setPixelSize 直接生效,无需先 setPointSizeF(-1)
|
||||
// (-1 会触发 QFont::setPointSizeF 警告刷屏日志)
|
||||
f.setWeight(QFont::Normal);
|
||||
painter->setFont(f);
|
||||
painter->setPen(tokenColor("text/tertiary"));
|
||||
|
|
|
|||
|
|
@ -169,6 +169,13 @@ bool CategorySection::passesFilters(const DsRow& row) const {
|
|||
}
|
||||
|
||||
void CategorySection::rebuildList() {
|
||||
// 增量保留:记住当前已勾选的 ds,重建后复原(仍存在的项保持勾选)。否则每次刷新(勾选对象/建体/
|
||||
// 存切片/建异常都会触发)清空全部勾选 → 渲染被重置,体验极差(用户反馈:必须增量更新)。
|
||||
std::set<std::string> wasChecked;
|
||||
for (QTreeWidgetItemIterator it(list_); *it; ++it)
|
||||
if ((*it)->checkState(0) == Qt::Checked)
|
||||
wasChecked.insert((*it)->data(0, kDsIdRole).toString().toStdString());
|
||||
|
||||
std::vector<DsRow> filtered;
|
||||
filtered.reserve(rows_.size());
|
||||
for (const auto& r : rows_)
|
||||
|
|
@ -219,7 +226,8 @@ void CategorySection::rebuildList() {
|
|||
continue;
|
||||
}
|
||||
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
||||
(*it)->setCheckState(0, Qt::Unchecked);
|
||||
const std::string id = (*it)->data(0, kDsIdRole).toString().toStdString();
|
||||
(*it)->setCheckState(0, wasChecked.count(id) ? Qt::Checked : Qt::Unchecked); // 复原勾选
|
||||
}
|
||||
}
|
||||
list_->expandAll(); // 展开容器层级(项目根/GS/TM),让体/切片/异常可见
|
||||
|
|
@ -230,7 +238,7 @@ void CategorySection::rebuildList() {
|
|||
if (!(*hit)->isHidden())
|
||||
contentH += (*hit)->text(0).contains(QLatin1Char('\n')) ? 52 : 30;
|
||||
list_->setMinimumHeight(contentH);
|
||||
emitChecked(); // 重建后必为空选,清掉上次渲染勾选
|
||||
emitChecked(); // 上抛复原后的勾选集(保持渲染,不再清空 → 控制器据 diff 增量保留已渲染图元)
|
||||
}
|
||||
|
||||
QStringList CategorySection::checkedDsIds() const {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ ColumnDrawer::ColumnDrawer(QWidget* parent, geopro::data::DatasetFieldDictionary
|
|||
body_ = tabs;
|
||||
tabs->addTab(analysisTab_, QStringLiteral("三维分析"));
|
||||
tabs->addTab(col2D_, QStringLiteral("二维分析"));
|
||||
tabs->tabBar()->setUsesScrollButtons(false); // 永不出左右滚动箭头(两 tab 必能平铺)
|
||||
|
||||
// 折叠按钮:固定宽 18px,垂直拉伸。
|
||||
// 用 SVG 图标(makeGlyph)而非 ◀/▶ 文字——三角符(U+25C0/25B6)不在 YaHei,作按钮文字会触发
|
||||
|
|
@ -61,7 +62,9 @@ void ColumnDrawer::resizeEvent(QResizeEvent* e)
|
|||
if (auto* tabs = qobject_cast<QTabWidget*>(body_)) {
|
||||
const int n = tabs->count();
|
||||
if (n > 0 && tabs->width() > 0) {
|
||||
const int w = std::max(40, tabs->width() / n - 6); // 减 margin-right(4)余量
|
||||
// 每 tab 内容宽 = 总宽/n - 每 tab 非内容开销(全局 QSS padding 8+16+16=… 约 32 + margin 4)。
|
||||
// 稍欠一点宽避免溢出(溢出会触发滚动箭头);setUsesScrollButtons(false) 再兜底。
|
||||
const int w = std::max(40, tabs->width() / n - 42);
|
||||
tabs->tabBar()->setStyleSheet(QStringLiteral("QTabBar::tab{width:%1px;}").arg(w));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue