fix(vtk): 坐标轴面板预热(4a)+装置枚举到达重刷下拉+树→VTK选中联动正向(②)
- 4a 坐标轴面板首开卡顿:启动时 ensurePolished+adjustSize 预热样式/布局,避免首次点开同步解析卡UI - 装置下拉空:枚举异步加载(可能晚于数据)→在 listArrayTypes 回调里 refreshArrayFilters 重填各段下拉 - ② 树选中切片/异常→VTK高亮:CategorySection 发 datasetSelected→main 对 dd_anomaly setSelectedAnomaly /dd_slice selectSavedSlice。反向(VTK→树)需拾取回调,并入 OPT-002 构建:app 链接通过
This commit is contained in:
parent
62b7cde5cd
commit
b2904c211e
|
|
@ -368,7 +368,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
auto* drawer = new geopro::app::ColumnDrawer(centerWidget, fieldDict);
|
auto* drawer = new geopro::app::ColumnDrawer(centerWidget, fieldDict);
|
||||||
auto* viewToolbar = new geopro::app::VtkViewToolbar(centerWidget); // VTK 画布全局视图控制竖排工具条
|
auto* viewToolbar = new geopro::app::VtkViewToolbar(centerWidget); // VTK 画布全局视图控制竖排工具条
|
||||||
// 拉装置类型枚举(全局,登录后一次)→ 填字典;电阻率/视电阻率段装置下拉据此显示 + 过滤(spec §6/§10)。
|
// 拉装置类型枚举(全局,登录后一次)→ 填字典;电阻率/视电阻率段装置下拉据此显示 + 过滤(spec §6/§10)。
|
||||||
cmdRepo.listArrayTypes([fieldDict](bool ok, QJsonArray list, QString) {
|
cmdRepo.listArrayTypes([fieldDict, drawer](bool ok, QJsonArray list, QString) {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
std::map<std::string, std::string> e;
|
std::map<std::string, std::string> e;
|
||||||
for (const auto& v : list) {
|
for (const auto& v : list) {
|
||||||
|
|
@ -378,6 +378,8 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
if (!iv.empty()) e[iv] = o.value(QStringLiteral("name")).toString().toStdString();
|
if (!iv.empty()) e[iv] = o.value(QStringLiteral("name")).toString().toStdString();
|
||||||
}
|
}
|
||||||
fieldDict->setArrayTypeEnum(std::move(e));
|
fieldDict->setArrayTypeEnum(std::move(e));
|
||||||
|
// 枚举到达(异步,可能晚于已加载的数据)→ 重填各段装置下拉,避免下拉为空。
|
||||||
|
drawer->analysisTab()->refreshArrayFilters();
|
||||||
});
|
});
|
||||||
// 左侧抽屉 | 右侧画布用 QSplitter(左面板可拖改宽);工具条悬浮于画布上(不占布局)。
|
// 左侧抽屉 | 右侧画布用 QSplitter(左面板可拖改宽);工具条悬浮于画布上(不占布局)。
|
||||||
auto* split = new QSplitter(Qt::Horizontal);
|
auto* split = new QSplitter(Qt::Horizontal);
|
||||||
|
|
@ -397,6 +399,10 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
// 坐标轴设置抽屉面板:叠加 vtkWidget、工具条右侧滑出,默认隐藏(点设置 toggle)。
|
// 坐标轴设置抽屉面板:叠加 vtkWidget、工具条右侧滑出,默认隐藏(点设置 toggle)。
|
||||||
auto* axesPanel = new geopro::app::AxesSettingsPanel(vtkWidget);
|
auto* axesPanel = new geopro::app::AxesSettingsPanel(vtkWidget);
|
||||||
axesPanel->hide();
|
axesPanel->hide();
|
||||||
|
// 预热:首次打开前先完成样式表解析 + 布局尺寸计算(含 spinbox/滑块/中文标签首次字体解析),
|
||||||
|
// 避免用户第一次点开时同步做这些导致 UI 卡顿。
|
||||||
|
axesPanel->ensurePolished();
|
||||||
|
axesPanel->adjustSize();
|
||||||
|
|
||||||
// 3b:三维分析栏勾选的已保存切片(dd_slice) id 集合 + 调和函数。
|
// 3b:三维分析栏勾选的已保存切片(dd_slice) id 集合 + 调和函数。
|
||||||
// syncSlices:按"当前活动体 dsId"调和 InteractionManager 上显示的已保存切片——
|
// syncSlices:按"当前活动体 dsId"调和 InteractionManager 上显示的已保存切片——
|
||||||
|
|
@ -912,6 +918,17 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
sceneView->setAnomalyVisible(id.toStdString(), vis);
|
sceneView->setAnomalyVisible(id.toStdString(), vis);
|
||||||
renderWindowPtr->Render();
|
renderWindowPtr->Render();
|
||||||
});
|
});
|
||||||
|
// 树选中切片/异常 → VTK 高亮联动(正向 list→VTK;反向 VTK→list 需拾取回调,见 OPT-002)。
|
||||||
|
QObject::connect(analysisTab, &geopro::app::CategoryAnalysisTab::datasetSelected, vtkWidget,
|
||||||
|
[sceneView, interactionMgr, renderWindowPtr](const QString& dsId,
|
||||||
|
const QString& ddCode) {
|
||||||
|
const std::string id = dsId.toStdString();
|
||||||
|
if (ddCode == QStringLiteral("dd_anomaly"))
|
||||||
|
sceneView->setSelectedAnomaly(id);
|
||||||
|
else if (ddCode == QStringLiteral("dd_slice"))
|
||||||
|
interactionMgr->selectSavedSlice(id); // 选中已渲染的该切片(高亮)
|
||||||
|
renderWindowPtr->Render();
|
||||||
|
});
|
||||||
// 异常双击属性(R83)/右键删除已并入 analysisTab 的 detailRequested(dd_anomaly) /
|
// 异常双击属性(R83)/右键删除已并入 analysisTab 的 detailRequested(dd_anomaly) /
|
||||||
// deleteDatasetRequested(dd_anomaly);列表选中→VTK高亮(R84)随旧栏退役暂缺,待新段补 anomalySelected。
|
// deleteDatasetRequested(dd_anomaly);列表选中→VTK高亮(R84)随旧栏退役暂缺,待新段补 anomalySelected。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
||||||
&CategoryAnalysisTab::sliceExportDatRequested);
|
&CategoryAnalysisTab::sliceExportDatRequested);
|
||||||
connect(sec, &CategorySection::anomalyVisibilityChanged, this,
|
connect(sec, &CategorySection::anomalyVisibilityChanged, this,
|
||||||
&CategoryAnalysisTab::anomalyVisibilityChanged);
|
&CategoryAnalysisTab::anomalyVisibilityChanged);
|
||||||
|
connect(sec, &CategorySection::datasetSelected, this, &CategoryAnalysisTab::datasetSelected);
|
||||||
// #7:各段等分 stretch → 内容都少时四段平分高度填满面板(初始与 VTK 区等高、不出滚动条);
|
// #7:各段等分 stretch → 内容都少时四段平分高度填满面板(初始与 VTK 区等高、不出滚动条);
|
||||||
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
||||||
col->addWidget(sec, 1);
|
col->addWidget(sec, 1);
|
||||||
|
|
@ -71,6 +72,10 @@ void CategoryAnalysisTab::setStructure(const std::vector<geopro::data::StructNod
|
||||||
for (auto& [id, sec] : sections_) sec->setStructure(nodes);
|
for (auto& [id, sec] : sections_) sec->setStructure(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CategoryAnalysisTab::refreshArrayFilters() {
|
||||||
|
for (auto& [id, sec] : sections_) sec->refreshArrayFilter();
|
||||||
|
}
|
||||||
|
|
||||||
CategorySection* CategoryAnalysisTab::section(const std::string& id) const {
|
CategorySection* CategoryAnalysisTab::section(const std::string& id) const {
|
||||||
const auto it = sections_.find(id);
|
const auto it = sections_.find(id);
|
||||||
return it != sections_.end() ? it->second : nullptr;
|
return it != sections_.end() ? it->second : nullptr;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public:
|
||||||
|
|
||||||
void setBuckets(const CategoryBuckets& b); // 分发到 5 段(与 categoryConfigs 同序)
|
void setBuckets(const CategoryBuckets& b); // 分发到 5 段(与 categoryConfigs 同序)
|
||||||
void setStructure(const std::vector<geopro::data::StructNode>& nodes); // 转发各段
|
void setStructure(const std::vector<geopro::data::StructNode>& nodes); // 转发各段
|
||||||
|
void refreshArrayFilters(); // 装置枚举异步加载后,重填各段装置筛选下拉
|
||||||
CategorySection* section(const std::string& id) const; // 按 CategorySpec.id 取段
|
CategorySection* section(const std::string& id) const; // 按 CategorySpec.id 取段
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
@ -40,6 +41,7 @@ signals:
|
||||||
void sliceExportImageRequested(const QString& dsId);
|
void sliceExportImageRequested(const QString& dsId);
|
||||||
void sliceExportDatRequested(const QString& dsId);
|
void sliceExportDatRequested(const QString& dsId);
|
||||||
void anomalyVisibilityChanged(const QString& dsId, bool vis);
|
void anomalyVisibilityChanged(const QString& dsId, bool vis);
|
||||||
|
void datasetSelected(const QString& dsId, const QString& ddCode); // 树选中→VTK 高亮联动
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void recomputeCheckedUnion();
|
void recomputeCheckedUnion();
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,15 @@ CategorySection::CategorySection(const CategorySpec& spec, geopro::data::Dataset
|
||||||
if (spec_.id == "voxel") { // 仅三维体段提供右键操作菜单(体/切片/异常)
|
if (spec_.id == "voxel") { // 仅三维体段提供右键操作菜单(体/切片/异常)
|
||||||
list_->setContextMenuPolicy(Qt::CustomContextMenu);
|
list_->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(list_, &QTreeWidget::customContextMenuRequested, this, &CategorySection::showContextMenu);
|
connect(list_, &QTreeWidget::customContextMenuRequested, this, &CategorySection::showContextMenu);
|
||||||
|
// 树选中切片/异常 → VTK 高亮联动(正向 list→VTK)。
|
||||||
|
connect(list_, &QTreeWidget::itemSelectionChanged, this, [this] {
|
||||||
|
const auto items = list_->selectedItems();
|
||||||
|
if (items.isEmpty()) return;
|
||||||
|
QTreeWidgetItem* it = items.first();
|
||||||
|
const QString id = it->data(0, kDsIdRole).toString();
|
||||||
|
const QString dd = it->data(0, kDsDdCodeRole).toString();
|
||||||
|
if (!id.isEmpty() && dd != QStringLiteral("container")) emit datasetSelected(id, dd);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
body->addWidget(list_, 1);
|
body->addWidget(list_, 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public:
|
||||||
void setDatasets(const std::vector<geopro::data::DsRow>& rows);
|
void setDatasets(const std::vector<geopro::data::DsRow>& rows);
|
||||||
void setChecked(const QString& dsId, bool on); // 按 dsId 勾选/取消(新建切片自动勾选等场景)
|
void setChecked(const QString& dsId, bool on); // 按 dsId 勾选/取消(新建切片自动勾选等场景)
|
||||||
QStringList checkedIds() const { return checkedDsIds(); } // 当前勾选 ds(异常显隐同步用)
|
QStringList checkedIds() const { return checkedDsIds(); } // 当前勾选 ds(异常显隐同步用)
|
||||||
|
void refreshArrayFilter() { refreshArrayCombo(); } // 装置枚举异步加载后重填下拉
|
||||||
const CategorySpec& spec() const { return spec_; }
|
const CategorySpec& spec() const { return spec_; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
@ -49,6 +50,7 @@ signals:
|
||||||
void sliceExportImageRequested(const QString& dsId); // 切片→导出图片
|
void sliceExportImageRequested(const QString& dsId); // 切片→导出图片
|
||||||
void sliceExportDatRequested(const QString& dsId); // 切片→导出 dat
|
void sliceExportDatRequested(const QString& dsId); // 切片→导出 dat
|
||||||
void anomalyVisibilityChanged(const QString& dsId, bool vis); // 异常→显示/隐藏
|
void anomalyVisibilityChanged(const QString& dsId, bool vis); // 异常→显示/隐藏
|
||||||
|
void datasetSelected(const QString& dsId, const QString& ddCode); // 树选中行→VTK 高亮联动(切片/异常)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)
|
void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue