From 5edfc8e5e830769592a7ca7dac05f66fd949adce Mon Sep 17 00:00:00 2001 From: gaozheng Date: Thu, 25 Jun 2026 21:12:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E8=A3=85=E7=BD=AE=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E7=A8=B3=E5=81=A5=E5=8C=B9=E9=85=8D+=E8=AF=8A=E6=96=AD?= =?UTF-8?q?=E6=97=A5=E5=BF=97=20+=20=E7=94=9F=E6=88=90=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=8B=E6=8B=89=E6=A1=86(=E6=A0=91=E5=BD=A2?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E9=9D=A2=E6=9D=BF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 装置下拉空:arrayTypeList 请求成功(日志确认),但匹配只认 itemValue(键)。改稳健匹配——ds 装置属性 存 itemValue 或中文名都认(命中键取中文名/命中值用原名),data 存实际属性值供 passesFilters 比对。 仍空则打 [arrayfilter] 诊断日志(枚举大小+首行属性 confFieldId=value)定位是枚举空还是值不匹配。 - 生成位置:QTreeWidget(常显树)→ QComboBox 下拉框,下拉面板用 QTreeView+QStandardItemModel 树模型 (GS/项目根/TM 层级);mountTargetId/confType 从树视图当前项读(树模型下比 combo currentData 可靠)。 构建:app 链接通过;434/434 测试通过 --- src/app/VolumeParamsDialog.cpp | 66 ++++++++++++++-------- src/app/VolumeParamsDialog.hpp | 2 +- src/app/panels/columns/CategorySection.cpp | 27 +++++++-- 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/app/VolumeParamsDialog.cpp b/src/app/VolumeParamsDialog.cpp index b3c9b82..9a2c17e 100644 --- a/src/app/VolumeParamsDialog.cpp +++ b/src/app/VolumeParamsDialog.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -111,38 +113,44 @@ VolumeParamsDialog::VolumeParamsDialog(const QVector& sources, form->addRow(formkit::editLabel(QStringLiteral("名称")), name_); cardLay->addLayout(form); - // 生成位置:GS/项目根/TM 层级树(单选),替代原扁平下拉。 - formkit::addSection(cardLay, QStringLiteral("生成位置"), card, false); - mountTree_ = new QTreeWidget(); - mountTree_->setHeaderHidden(true); - mountTree_->setIndentation(14); - mountTree_->setMaximumHeight(geopro::app::scaledPx(160)); + auto* form2 = formkit::makeEditForm(); + + // 生成位置:下拉框,下拉面板=GS/项目根/TM 层级树(QComboBox + QTreeView 视图 + 树模型)。 + mount_ = new QComboBox(); { - QHash mItems; + auto* model = new QStandardItemModel(mount_); + QHash mItems; for (const auto& n : structure) { - auto* it = new QTreeWidgetItem(); - it->setText(0, QString::fromStdString(n.name)); - it->setData(0, kRoleMountId, QString::fromStdString(n.id)); - it->setData(0, kRoleMountConfType, n.type == 2 ? 2 : 1); + auto* it = new QStandardItem(QString::fromStdString(n.name)); + it->setEditable(false); + it->setData(QString::fromStdString(n.id), kRoleMountId); + it->setData(n.type == 2 ? 2 : 1, kRoleMountConfType); mItems.insert(QString::fromStdString(n.id), it); } for (const auto& n : structure) { auto* it = mItems.value(QString::fromStdString(n.id)); auto* par = mItems.value(QString::fromStdString(n.parentId), nullptr); if (par) - par->addChild(it); + par->appendRow(it); else - mountTree_->addTopLevelItem(it); + model->appendRow(it); + } + auto* view = new QTreeView(mount_); + view->setHeaderHidden(true); + view->setItemsExpandable(true); + mount_->setModel(model); + mount_->setView(view); + view->expandAll(); + // 默认选中:指定的 defaultMountId,否则首个节点。view 当前项决定 mountTargetId;combo 显示尽力。 + QStandardItem* def = mItems.value(defaultMountId, nullptr); + if (!def && model->rowCount() > 0) def = model->item(0); + if (def) { + view->setCurrentIndex(def->index()); // 决定 mountTargetId/mountConfType 返回值 + mount_->setCurrentText(def->text()); // 顶层项可正确显示;嵌套项尽力(功能不受影响) } - mountTree_->expandAll(); - // 默认选中:指定的 defaultMountId,否则首个节点。 - QTreeWidgetItem* def = mItems.value(defaultMountId, nullptr); - if (!def && mountTree_->topLevelItemCount() > 0) def = mountTree_->topLevelItem(0); - if (def) mountTree_->setCurrentItem(def); } - cardLay->addWidget(mountTree_); - - auto* form2 = formkit::makeEditForm(); + formkit::capField(mount_); + form2->addRow(formkit::editLabel(QStringLiteral("生成位置")), mount_); model_ = new EmptyAwareComboBox(); model_->addItem(QStringLiteral("反距离加权 (IDW)"), static_cast(geopro::data::VolumeBuildParams::Model::Idw)); @@ -204,14 +212,22 @@ QStringList VolumeParamsDialog::sourceDatasetIds() const { return ids; } +namespace { +// 从生成位置下拉的树视图取当前选中项(树模型下比 combo->currentData 可靠)。 +QModelIndex mountCurrentIndex(QComboBox* mount) { + auto* view = qobject_cast(mount->view()); + return view ? view->currentIndex() : QModelIndex(); +} +} // namespace + QString VolumeParamsDialog::mountTargetId() const { - auto* it = mountTree_->currentItem(); - return it ? it->data(0, kRoleMountId).toString() : QString(); + const QModelIndex idx = mountCurrentIndex(mount_); + return idx.isValid() ? idx.data(kRoleMountId).toString() : QString(); } int VolumeParamsDialog::mountConfType() const { - auto* it = mountTree_->currentItem(); - const int ct = it ? it->data(0, kRoleMountConfType).toInt() : 0; + const QModelIndex idx = mountCurrentIndex(mount_); + const int ct = idx.isValid() ? idx.data(kRoleMountConfType).toInt() : 0; return ct == 0 ? 1 : ct; // 缺省按 GS/项目根 } diff --git a/src/app/VolumeParamsDialog.hpp b/src/app/VolumeParamsDialog.hpp index dccafbb..98cbf86 100644 --- a/src/app/VolumeParamsDialog.hpp +++ b/src/app/VolumeParamsDialog.hpp @@ -47,7 +47,7 @@ private: QDoubleSpinBox* power_ = nullptr; QDoubleSpinBox* maxDist_ = nullptr; QTreeWidget* sourceTree_ = nullptr; // 左:源数据集树(可勾选) - QTreeWidget* mountTree_ = nullptr; // 右:生成位置树(单选) + QComboBox* mount_ = nullptr; // 右:生成位置下拉(下拉面板是 GS/项目根/TM 层级树) }; } // namespace geopro::app diff --git a/src/app/panels/columns/CategorySection.cpp b/src/app/panels/columns/CategorySection.cpp index 1e7a654..1034565 100644 --- a/src/app/panels/columns/CategorySection.cpp +++ b/src/app/panels/columns/CategorySection.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include "panels/columns/DateRangeEdit.hpp" @@ -159,17 +160,33 @@ void CategorySection::refreshArrayCombo() { if (dict_) { const auto& en = dict_->arrayTypeEnum(); // 全局装置枚举 itemValue→中文 QSet seen; - // 列出当前数据里出现过、且命中枚举的装置值 → 中文名。 + // 列出当前数据里出现过的装置值 → 中文名。兼容 ds 把装置存成 itemValue(键) 或中文名(值) 两种形态。 for (const auto& r : rows_) { for (const auto& kv : r.properties) { - const auto it = en.find(kv.value); - if (it == en.end()) continue; // 非装置类型值 const QString val = QString::fromStdString(kv.value); - if (seen.contains(val)) continue; + QString name; + const auto it = en.find(kv.value); + if (it != en.end()) { + name = QString::fromStdString(it->second); // value 是 itemValue → 取中文名 + } else { + for (const auto& e : en) // value 可能直接是中文名 + if (QString::fromStdString(e.second) == val) { name = val; break; } + } + if (name.isEmpty() || seen.contains(val)) continue; seen.insert(val); - arrayCombo_->addItem(QString::fromStdString(it->second), val); + arrayCombo_->addItem(name, val); // data=实际属性值(passesFilters 据此比对) } } + if (arrayCombo_->count() <= 1) // 诊断:装置下拉仍空 → 打印枚举大小 + 首行属性,定位是枚举空还是值不匹配 + qInfo().noquote() << "[arrayfilter]" << QString::fromStdString(spec_.id) << "enum=" + << en.size() << "rows=" << rows_.size() + << (rows_.empty() ? QString() : [&] { + QStringList vs; + for (const auto& kv : rows_.front().properties) + vs << (QString::fromStdString(kv.confFieldId) + "=" + + QString::fromStdString(kv.value)); + return "row0[" + vs.join(',') + "]"; + }()); } const int idx = arrayCombo_->findData(prev); // 尽量保留上次选择 arrayCombo_->setCurrentIndex(idx >= 0 ? idx : 0);