From 389a2da7443b7feda74c3be04eb70ac58e4739e2 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 10 Jun 2026 09:40:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(ela):=20=E8=A1=A8=E6=A0=BC=E2=86=92ElaTabl?= =?UTF-8?q?eWidget(=E7=9B=B4=E6=9B=BF)=20+=20=E5=AF=B9=E8=B1=A1=E6=A0=91?= =?UTF-8?q?=E2=86=92ElaTreeView+QStandardItemModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ProjectListDialog: QTableWidget → ElaTableWidget(item 版直接继承 QTableWidget, 1 行) - ObjectTreePanel: QTreeWidget → ElaTreeView + Qt 自带 QStandardItemModel(非手写 model); QTreeWidgetItem→QStandardItem, 勾选/点击逻辑改按 QModelIndex/itemChanged; ElaTreeView 自绘 展开折叠指示(去掉自定义 chevron QSS); 行为(TM 勾选/点击发 tmClicked/tmCheckToggled)保持 --- src/app/ProjectListDialog.cpp | 3 +- src/app/panels/ObjectTreePanel.cpp | 59 ++++++++++++++---------------- src/app/panels/ObjectTreePanel.hpp | 6 ++- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/app/ProjectListDialog.cpp b/src/app/ProjectListDialog.cpp index cbc7531..46ccffa 100644 --- a/src/app/ProjectListDialog.cpp +++ b/src/app/ProjectListDialog.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace geopro::app { namespace { @@ -66,7 +67,7 @@ ProjectListDialog::ProjectListDialog(data::IProjectRepository& repo, QWidget* pa filter->addStretch(); root->addLayout(filter); - table_ = new QTableWidget(this); + table_ = new ElaTableWidget(this); // Ela item 版表格(继承 QTableWidget),直替 table_->setColumnCount(8); table_->setHorizontalHeaderLabels(QStringList{ QStringLiteral("序号"), QStringLiteral("项目名称"), QStringLiteral("项目编号"), diff --git a/src/app/panels/ObjectTreePanel.cpp b/src/app/panels/ObjectTreePanel.cpp index 66c1ea7..a550089 100644 --- a/src/app/panels/ObjectTreePanel.cpp +++ b/src/app/panels/ObjectTreePanel.cpp @@ -1,13 +1,15 @@ #include "panels/ObjectTreePanel.hpp" -#include #include +#include #include -#include -#include +#include +#include +#include #include -#include "Glyphs.hpp" +#include + #include "Theme.hpp" #include "dto/NavDto.hpp" @@ -17,15 +19,16 @@ namespace { // TM 节点把 tmObjectId 存在该角色;GS/项目根节点为空。 constexpr int kRoleTmId = Qt::UserRole + 2; -void addNodes(QTreeWidgetItem* parent, const std::vector& nodes) { +void addNodes(QStandardItem* parent, const std::vector& nodes) { for (const auto& n : nodes) { - auto* item = new QTreeWidgetItem(parent); - item->setText(0, QString::fromStdString(n.node.name)); + auto* item = new QStandardItem(QString::fromStdString(n.node.name)); + item->setEditable(false); if (n.isTm) { - item->setData(0, kRoleTmId, QString::fromStdString(n.node.id)); - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - item->setCheckState(0, Qt::Unchecked); // 真实数据渲染下一轮接入,默认不勾 + item->setData(QString::fromStdString(n.node.id), kRoleTmId); + item->setCheckable(true); + item->setCheckState(Qt::Unchecked); // 真实数据渲染下一轮接入,默认不勾 } + parent->appendRow(item); addNodes(item, n.children); } } @@ -36,19 +39,10 @@ ObjectTreePanel::ObjectTreePanel(QWidget* parent) : QWidget(parent) { lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); - tree_ = new QTreeWidget(this); + tree_ = new ElaTreeView(this); // Fluent 树视图(自绘展开/折叠指示,随主题) tree_->setHeaderHidden(true); - { - const QString openArrow = writeChevronIcon(true, QColor("#8A93A3")); - const QString closedArrow = writeChevronIcon(false, QColor("#8A93A3")); - geopro::app::applyThemedStyleSheet( - tree_, QStringLiteral("QTreeView::branch { background: #FFFFFF; }" - "QTreeView::branch:has-children:!has-siblings:closed," - "QTreeView::branch:closed:has-children:has-siblings { image: url(%1); }" - "QTreeView::branch:open:has-children:!has-siblings," - "QTreeView::branch:open:has-children:has-siblings { image: url(%2); }") - .arg(closedArrow, openArrow)); - } + model_ = new QStandardItemModel(tree_); + tree_->setModel(model_); lay->addWidget(tree_, 1); hint_ = new QLabel(QStringLiteral("正在加载对象…"), this); @@ -57,21 +51,22 @@ ObjectTreePanel::ObjectTreePanel(QWidget* parent) : QWidget(parent) { hint_->setVisible(false); lay->addWidget(hint_); - QObject::connect(tree_, &QTreeWidget::itemClicked, this, [this](QTreeWidgetItem* item, int) { - const QString tmId = item->data(0, kRoleTmId).toString(); + // 单击 TM → tmClicked(按 index 取 tmId)。 + QObject::connect(tree_, &QTreeView::clicked, this, [this](const QModelIndex& idx) { + const QString tmId = idx.data(kRoleTmId).toString(); if (!tmId.isEmpty()) emit tmClicked(tmId); }); - QObject::connect(tree_, &QTreeWidget::itemChanged, this, [this](QTreeWidgetItem* item, int) { - const QString tmId = item->data(0, kRoleTmId).toString(); - if (!tmId.isEmpty()) - emit tmCheckToggled(tmId, item->checkState(0) == Qt::Checked); + // 勾选变化 → tmCheckToggled。 + QObject::connect(model_, &QStandardItemModel::itemChanged, this, [this](QStandardItem* item) { + const QString tmId = item->data(kRoleTmId).toString(); + if (!tmId.isEmpty()) emit tmCheckToggled(tmId, item->checkState() == Qt::Checked); }); } void ObjectTreePanel::setStructure(const QString& projectName, const std::vector& nodes) { - const QSignalBlocker block(tree_); // 重建触发 itemChanged,先屏蔽 - tree_->clear(); + const QSignalBlocker block(model_); // 重建触发 itemChanged,先屏蔽 + model_->clear(); const auto roots = data::dto::buildStructTree(nodes); if (roots.empty()) { showMessage(projectName.isEmpty() ? QStringLiteral("(暂无项目)") @@ -80,12 +75,12 @@ void ObjectTreePanel::setStructure(const QString& projectName, } hint_->setVisible(false); tree_->setVisible(true); - addNodes(tree_->invisibleRootItem(), roots); // 结构已含项目根节点,直接渲染 + addNodes(model_->invisibleRootItem(), roots); // 结构已含项目根节点,直接渲染 tree_->expandAll(); } void ObjectTreePanel::showMessage(const QString& message) { - tree_->clear(); + model_->clear(); tree_->setVisible(false); hint_->setText(message); hint_->setVisible(true); diff --git a/src/app/panels/ObjectTreePanel.hpp b/src/app/panels/ObjectTreePanel.hpp index 3621386..33cfff4 100644 --- a/src/app/panels/ObjectTreePanel.hpp +++ b/src/app/panels/ObjectTreePanel.hpp @@ -3,7 +3,8 @@ #include #include "repo/RepoTypes.hpp" -class QTreeWidget; +class QTreeView; +class QStandardItemModel; class QLabel; namespace geopro::app { @@ -24,7 +25,8 @@ signals: void tmCheckToggled(const QString& tmObjectId, bool checked); private: - QTreeWidget* tree_ = nullptr; + QTreeView* tree_ = nullptr; // ElaTreeView(继承 QTreeView) + QStandardItemModel* model_ = nullptr; // 标准 model(Qt 自带) QLabel* hint_ = nullptr; };