feat(ela): 表格→ElaTableWidget(直替) + 对象树→ElaTreeView+QStandardItemModel
- ProjectListDialog: QTableWidget → ElaTableWidget(item 版直接继承 QTableWidget, 1 行) - ObjectTreePanel: QTreeWidget → ElaTreeView + Qt 自带 QStandardItemModel(非手写 model); QTreeWidgetItem→QStandardItem, 勾选/点击逻辑改按 QModelIndex/itemChanged; ElaTreeView 自绘 展开折叠指示(去掉自定义 chevron QSS); 行为(TM 勾选/点击发 tmClicked/tmCheckToggled)保持
This commit is contained in:
parent
68d832c57b
commit
389a2da744
|
|
@ -19,6 +19,7 @@
|
||||||
#include <ElaComboBox.h>
|
#include <ElaComboBox.h>
|
||||||
#include <ElaLineEdit.h>
|
#include <ElaLineEdit.h>
|
||||||
#include <ElaPushButton.h>
|
#include <ElaPushButton.h>
|
||||||
|
#include <ElaTableWidget.h>
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -66,7 +67,7 @@ ProjectListDialog::ProjectListDialog(data::IProjectRepository& repo, QWidget* pa
|
||||||
filter->addStretch();
|
filter->addStretch();
|
||||||
root->addLayout(filter);
|
root->addLayout(filter);
|
||||||
|
|
||||||
table_ = new QTableWidget(this);
|
table_ = new ElaTableWidget(this); // Ela item 版表格(继承 QTableWidget),直替
|
||||||
table_->setColumnCount(8);
|
table_->setColumnCount(8);
|
||||||
table_->setHorizontalHeaderLabels(QStringList{
|
table_->setHorizontalHeaderLabels(QStringList{
|
||||||
QStringLiteral("序号"), QStringLiteral("项目名称"), QStringLiteral("项目编号"),
|
QStringLiteral("序号"), QStringLiteral("项目名称"), QStringLiteral("项目编号"),
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
#include "panels/ObjectTreePanel.hpp"
|
#include "panels/ObjectTreePanel.hpp"
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QModelIndex>
|
||||||
#include <QSignalBlocker>
|
#include <QSignalBlocker>
|
||||||
#include <QTreeWidget>
|
#include <QStandardItem>
|
||||||
#include <QTreeWidgetItem>
|
#include <QStandardItemModel>
|
||||||
|
#include <QTreeView>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include "Glyphs.hpp"
|
#include <ElaTreeView.h>
|
||||||
|
|
||||||
#include "Theme.hpp"
|
#include "Theme.hpp"
|
||||||
#include "dto/NavDto.hpp"
|
#include "dto/NavDto.hpp"
|
||||||
|
|
||||||
|
|
@ -17,15 +19,16 @@ namespace {
|
||||||
// TM 节点把 tmObjectId 存在该角色;GS/项目根节点为空。
|
// TM 节点把 tmObjectId 存在该角色;GS/项目根节点为空。
|
||||||
constexpr int kRoleTmId = Qt::UserRole + 2;
|
constexpr int kRoleTmId = Qt::UserRole + 2;
|
||||||
|
|
||||||
void addNodes(QTreeWidgetItem* parent, const std::vector<data::dto::StructTreeNode>& nodes) {
|
void addNodes(QStandardItem* parent, const std::vector<data::dto::StructTreeNode>& nodes) {
|
||||||
for (const auto& n : nodes) {
|
for (const auto& n : nodes) {
|
||||||
auto* item = new QTreeWidgetItem(parent);
|
auto* item = new QStandardItem(QString::fromStdString(n.node.name));
|
||||||
item->setText(0, QString::fromStdString(n.node.name));
|
item->setEditable(false);
|
||||||
if (n.isTm) {
|
if (n.isTm) {
|
||||||
item->setData(0, kRoleTmId, QString::fromStdString(n.node.id));
|
item->setData(QString::fromStdString(n.node.id), kRoleTmId);
|
||||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
item->setCheckable(true);
|
||||||
item->setCheckState(0, Qt::Unchecked); // 真实数据渲染下一轮接入,默认不勾
|
item->setCheckState(Qt::Unchecked); // 真实数据渲染下一轮接入,默认不勾
|
||||||
}
|
}
|
||||||
|
parent->appendRow(item);
|
||||||
addNodes(item, n.children);
|
addNodes(item, n.children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,19 +39,10 @@ ObjectTreePanel::ObjectTreePanel(QWidget* parent) : QWidget(parent) {
|
||||||
lay->setContentsMargins(0, 0, 0, 0);
|
lay->setContentsMargins(0, 0, 0, 0);
|
||||||
lay->setSpacing(0);
|
lay->setSpacing(0);
|
||||||
|
|
||||||
tree_ = new QTreeWidget(this);
|
tree_ = new ElaTreeView(this); // Fluent 树视图(自绘展开/折叠指示,随主题)
|
||||||
tree_->setHeaderHidden(true);
|
tree_->setHeaderHidden(true);
|
||||||
{
|
model_ = new QStandardItemModel(tree_);
|
||||||
const QString openArrow = writeChevronIcon(true, QColor("#8A93A3"));
|
tree_->setModel(model_);
|
||||||
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));
|
|
||||||
}
|
|
||||||
lay->addWidget(tree_, 1);
|
lay->addWidget(tree_, 1);
|
||||||
|
|
||||||
hint_ = new QLabel(QStringLiteral("正在加载对象…"), this);
|
hint_ = new QLabel(QStringLiteral("正在加载对象…"), this);
|
||||||
|
|
@ -57,21 +51,22 @@ ObjectTreePanel::ObjectTreePanel(QWidget* parent) : QWidget(parent) {
|
||||||
hint_->setVisible(false);
|
hint_->setVisible(false);
|
||||||
lay->addWidget(hint_);
|
lay->addWidget(hint_);
|
||||||
|
|
||||||
QObject::connect(tree_, &QTreeWidget::itemClicked, this, [this](QTreeWidgetItem* item, int) {
|
// 单击 TM → tmClicked(按 index 取 tmId)。
|
||||||
const QString tmId = item->data(0, kRoleTmId).toString();
|
QObject::connect(tree_, &QTreeView::clicked, this, [this](const QModelIndex& idx) {
|
||||||
|
const QString tmId = idx.data(kRoleTmId).toString();
|
||||||
if (!tmId.isEmpty()) emit tmClicked(tmId);
|
if (!tmId.isEmpty()) emit tmClicked(tmId);
|
||||||
});
|
});
|
||||||
QObject::connect(tree_, &QTreeWidget::itemChanged, this, [this](QTreeWidgetItem* item, int) {
|
// 勾选变化 → tmCheckToggled。
|
||||||
const QString tmId = item->data(0, kRoleTmId).toString();
|
QObject::connect(model_, &QStandardItemModel::itemChanged, this, [this](QStandardItem* item) {
|
||||||
if (!tmId.isEmpty())
|
const QString tmId = item->data(kRoleTmId).toString();
|
||||||
emit tmCheckToggled(tmId, item->checkState(0) == Qt::Checked);
|
if (!tmId.isEmpty()) emit tmCheckToggled(tmId, item->checkState() == Qt::Checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTreePanel::setStructure(const QString& projectName,
|
void ObjectTreePanel::setStructure(const QString& projectName,
|
||||||
const std::vector<data::StructNode>& nodes) {
|
const std::vector<data::StructNode>& nodes) {
|
||||||
const QSignalBlocker block(tree_); // 重建触发 itemChanged,先屏蔽
|
const QSignalBlocker block(model_); // 重建触发 itemChanged,先屏蔽
|
||||||
tree_->clear();
|
model_->clear();
|
||||||
const auto roots = data::dto::buildStructTree(nodes);
|
const auto roots = data::dto::buildStructTree(nodes);
|
||||||
if (roots.empty()) {
|
if (roots.empty()) {
|
||||||
showMessage(projectName.isEmpty() ? QStringLiteral("(暂无项目)")
|
showMessage(projectName.isEmpty() ? QStringLiteral("(暂无项目)")
|
||||||
|
|
@ -80,12 +75,12 @@ void ObjectTreePanel::setStructure(const QString& projectName,
|
||||||
}
|
}
|
||||||
hint_->setVisible(false);
|
hint_->setVisible(false);
|
||||||
tree_->setVisible(true);
|
tree_->setVisible(true);
|
||||||
addNodes(tree_->invisibleRootItem(), roots); // 结构已含项目根节点,直接渲染
|
addNodes(model_->invisibleRootItem(), roots); // 结构已含项目根节点,直接渲染
|
||||||
tree_->expandAll();
|
tree_->expandAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectTreePanel::showMessage(const QString& message) {
|
void ObjectTreePanel::showMessage(const QString& message) {
|
||||||
tree_->clear();
|
model_->clear();
|
||||||
tree_->setVisible(false);
|
tree_->setVisible(false);
|
||||||
hint_->setText(message);
|
hint_->setText(message);
|
||||||
hint_->setVisible(true);
|
hint_->setVisible(true);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "repo/RepoTypes.hpp"
|
#include "repo/RepoTypes.hpp"
|
||||||
|
|
||||||
class QTreeWidget;
|
class QTreeView;
|
||||||
|
class QStandardItemModel;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
@ -24,7 +25,8 @@ signals:
|
||||||
void tmCheckToggled(const QString& tmObjectId, bool checked);
|
void tmCheckToggled(const QString& tmObjectId, bool checked);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTreeWidget* tree_ = nullptr;
|
QTreeView* tree_ = nullptr; // ElaTreeView(继承 QTreeView)
|
||||||
|
QStandardItemModel* model_ = nullptr; // 标准 model(Qt 自带)
|
||||||
QLabel* hint_ = nullptr;
|
QLabel* hint_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue