fix(vtk): 修审查问题(H1 setDatasets信号风暴/H2异步陈旧批次竞态/I1全屏按钮互斥)
This commit is contained in:
parent
24d88530af
commit
5e15941cd2
|
|
@ -62,6 +62,7 @@
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
|
#include <QSignalBlocker>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
|
@ -593,9 +594,11 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
|
|
||||||
// ── 左上对象树勾选 → 拉取各 TM 的 ds 子树,按维度分发到三栏列表(spec §6.1/§8)──
|
// ── 左上对象树勾选 → 拉取各 TM 的 ds 子树,按维度分发到三栏列表(spec §6.1/§8)──
|
||||||
// 渲染由三栏勾选框驱动(Task 7:Column3DDataset::checkedDatasetsChanged → setCheckedDatasets)。
|
// 渲染由三栏勾选框驱动(Task 7:Column3DDataset::checkedDatasetsChanged → setCheckedDatasets)。
|
||||||
|
auto generation = std::make_shared<unsigned long long>(0);
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
objectTree, &geopro::app::ObjectTreePanel::checkedTmsChanged, &window,
|
objectTree, &geopro::app::ObjectTreePanel::checkedTmsChanged, &window,
|
||||||
[&projectRepo, &nav, drawer, emptyState](const QStringList& tmIds) {
|
[&projectRepo, &nav, drawer, emptyState, generation](const QStringList& tmIds) {
|
||||||
|
const unsigned long long myGen = ++(*generation);
|
||||||
emptyState->setVisible(tmIds.isEmpty()); // 有勾选→隐藏引导层,露出中央渲染
|
emptyState->setVisible(tmIds.isEmpty()); // 有勾选→隐藏引导层,露出中央渲染
|
||||||
if (tmIds.isEmpty()) {
|
if (tmIds.isEmpty()) {
|
||||||
drawer->col3D()->setDatasets({});
|
drawer->col3D()->setDatasets({});
|
||||||
|
|
@ -606,7 +609,8 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
// 多 TM 异步汇总:每个 TM 取整棵 ds 子树,全部回来后按维度分发到三栏。
|
// 多 TM 异步汇总:每个 TM 取整棵 ds 子树,全部回来后按维度分发到三栏。
|
||||||
auto acc = std::make_shared<std::vector<geopro::data::DsRow>>();
|
auto acc = std::make_shared<std::vector<geopro::data::DsRow>>();
|
||||||
auto remaining = std::make_shared<int>(tmIds.size());
|
auto remaining = std::make_shared<int>(tmIds.size());
|
||||||
auto finish = [acc, drawer]() {
|
auto finish = [acc, drawer, generation, myGen]() {
|
||||||
|
if (*generation != myGen) return; // 已被更新的勾选批次取代→丢弃陈旧结果
|
||||||
geopro::app::DimBuckets b = geopro::app::splitByDimension(*acc);
|
geopro::app::DimBuckets b = geopro::app::splitByDimension(*acc);
|
||||||
drawer->col3D()->setDatasets(b.dim3D);
|
drawer->col3D()->setDatasets(b.dim3D);
|
||||||
drawer->col2D()->setDatasets(b.dim2D);
|
drawer->col2D()->setDatasets(b.dim2D);
|
||||||
|
|
@ -771,14 +775,22 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
if (vtkFsBtn) {
|
if (vtkFsBtn) {
|
||||||
vtkFsBtn->setCheckable(true);
|
vtkFsBtn->setCheckable(true);
|
||||||
QObject::connect(vtkFsBtn, &QToolButton::toggled, &window,
|
QObject::connect(vtkFsBtn, &QToolButton::toggled, &window,
|
||||||
[applyFullscreen, vtkDock, allDocks](bool on) {
|
[applyFullscreen, vtkDock, allDocks, detailFsBtn](bool on) {
|
||||||
|
if (on && detailFsBtn && detailFsBtn->isChecked()) {
|
||||||
|
QSignalBlocker b(detailFsBtn);
|
||||||
|
detailFsBtn->setChecked(false);
|
||||||
|
}
|
||||||
applyFullscreen(vtkDock, allDocks, on);
|
applyFullscreen(vtkDock, allDocks, on);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (detailFsBtn) {
|
if (detailFsBtn) {
|
||||||
detailFsBtn->setCheckable(true);
|
detailFsBtn->setCheckable(true);
|
||||||
QObject::connect(detailFsBtn, &QToolButton::toggled, &window,
|
QObject::connect(detailFsBtn, &QToolButton::toggled, &window,
|
||||||
[applyFullscreen, detailDock, allDocks](bool on) {
|
[applyFullscreen, detailDock, allDocks, vtkFsBtn](bool on) {
|
||||||
|
if (on && vtkFsBtn && vtkFsBtn->isChecked()) {
|
||||||
|
QSignalBlocker b(vtkFsBtn);
|
||||||
|
vtkFsBtn->setChecked(false);
|
||||||
|
}
|
||||||
applyFullscreen(detailDock, allDocks, on);
|
applyFullscreen(detailDock, allDocks, on);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QSignalBlocker>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QTreeWidgetItemIterator>
|
#include <QTreeWidgetItemIterator>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
@ -78,12 +79,20 @@ Column2DDataset::Column2DDataset(QWidget* parent) : QWidget(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Column2DDataset::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
void Column2DDataset::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
||||||
|
{
|
||||||
|
QSignalBlocker blocker(list_);
|
||||||
populateDatasetList(list_, rows, /*append=*/false);
|
populateDatasetList(list_, rows, /*append=*/false);
|
||||||
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
|
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
|
||||||
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
||||||
if ((*it)->checkState(0) != Qt::Checked)
|
|
||||||
(*it)->setCheckState(0, Qt::Unchecked);
|
(*it)->setCheckState(0, Qt::Unchecked);
|
||||||
}
|
}
|
||||||
|
} // blocker released here
|
||||||
|
// 填充后统一发一次(新载入必为空选):清掉上一次的渲染勾选
|
||||||
|
QStringList ids;
|
||||||
|
for (QTreeWidgetItemIterator it(list_); *it; ++it)
|
||||||
|
if ((*it)->checkState(0) == Qt::Checked)
|
||||||
|
ids << (*it)->data(0, kDsIdRole).toString();
|
||||||
|
emit checkedDatasetsChanged(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "panels/columns/Column3DAnalysis.hpp"
|
#include "panels/columns/Column3DAnalysis.hpp"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QSignalBlocker>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QTreeWidgetItemIterator>
|
#include <QTreeWidgetItemIterator>
|
||||||
|
|
@ -37,12 +38,20 @@ Column3DAnalysis::Column3DAnalysis(QWidget* parent) : QWidget(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Column3DAnalysis::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
void Column3DAnalysis::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
||||||
|
{
|
||||||
|
QSignalBlocker blocker(tree_);
|
||||||
populateDatasetList(tree_, rows, /*append=*/false);
|
populateDatasetList(tree_, rows, /*append=*/false);
|
||||||
for (QTreeWidgetItemIterator it(tree_); *it; ++it) {
|
for (QTreeWidgetItemIterator it(tree_); *it; ++it) {
|
||||||
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
||||||
if ((*it)->checkState(0) != Qt::Checked)
|
|
||||||
(*it)->setCheckState(0, Qt::Unchecked);
|
(*it)->setCheckState(0, Qt::Unchecked);
|
||||||
}
|
}
|
||||||
|
} // blocker released here
|
||||||
|
// 填充后统一发一次(新载入必为空选):清掉上一次的渲染勾选
|
||||||
|
QStringList ids;
|
||||||
|
for (QTreeWidgetItemIterator it(tree_); *it; ++it)
|
||||||
|
if ((*it)->checkState(0) == Qt::Checked)
|
||||||
|
ids << (*it)->data(0, kDsIdRole).toString();
|
||||||
|
emit checkedItemsChanged(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Column3DAnalysis::onContextMenu(const QPoint& pos) {
|
void Column3DAnalysis::onContextMenu(const QPoint& pos) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class Column3DAnalysis : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Column3DAnalysis(QWidget* parent = nullptr);
|
explicit Column3DAnalysis(QWidget* parent = nullptr);
|
||||||
|
// 本期:按 ds parentId 建树(切片挂源数据下);完整 对象→三维体→切片 三级树待后端数据(P4)。
|
||||||
void setDatasets(const std::vector<geopro::data::DsRow>& rows); // Analysis 维度(三维体/切片)
|
void setDatasets(const std::vector<geopro::data::DsRow>& rows); // Analysis 维度(三维体/切片)
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QSignalBlocker>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QTreeWidgetItemIterator>
|
#include <QTreeWidgetItemIterator>
|
||||||
|
|
@ -125,12 +126,20 @@ Column3DDataset::Column3DDataset(QWidget* parent) : QWidget(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Column3DDataset::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
void Column3DDataset::setDatasets(const std::vector<geopro::data::DsRow>& rows) {
|
||||||
|
{
|
||||||
|
QSignalBlocker blocker(list_);
|
||||||
populateDatasetList(list_, rows, /*append=*/false);
|
populateDatasetList(list_, rows, /*append=*/false);
|
||||||
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
|
for (QTreeWidgetItemIterator it(list_); *it; ++it) {
|
||||||
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
(*it)->setFlags((*it)->flags() | Qt::ItemIsUserCheckable);
|
||||||
if ((*it)->checkState(0) != Qt::Checked)
|
|
||||||
(*it)->setCheckState(0, Qt::Unchecked);
|
(*it)->setCheckState(0, Qt::Unchecked);
|
||||||
}
|
}
|
||||||
|
} // blocker released here
|
||||||
|
// 填充后统一发一次(新载入必为空选):清掉上一次的渲染勾选
|
||||||
|
QStringList ids;
|
||||||
|
for (QTreeWidgetItemIterator it(list_); *it; ++it)
|
||||||
|
if ((*it)->checkState(0) == Qt::Checked)
|
||||||
|
ids << (*it)->data(0, kDsIdRole).toString();
|
||||||
|
emit checkedDatasetsChanged(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace geopro::app
|
} // namespace geopro::app
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue