feat(ui): ObjectExceptionPanel 异常+异常体只读树(含详情展开)

This commit is contained in:
gaozheng 2026-06-10 20:44:25 +08:00
parent 5686155faa
commit 595d65cd3b
3 changed files with 109 additions and 0 deletions

View File

@ -25,6 +25,7 @@ add_executable(geopro_desktop WIN32
panels/DatasetListPanel.cpp
panels/ObjectTreePanel.cpp
panels/DynamicFormView.cpp
panels/ObjectExceptionPanel.cpp
CentralScene.cpp
ProjectListDialog.cpp
SettingsDialog.cpp)

View File

@ -0,0 +1,85 @@
#include "panels/ObjectExceptionPanel.hpp"
#include <QLabel>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QVBoxLayout>
#include "Theme.hpp"
namespace geopro::app {
namespace {
QTreeWidgetItem* addException(QTreeWidgetItem* parent, const geopro::data::ExceptionRow& e) {
auto* item = new QTreeWidgetItem(parent);
const QString type =
e.typeName.empty() ? QString() : QStringLiteral("%1").arg(QString::fromStdString(e.typeName));
item->setText(0, QString::fromStdString(e.name) + type);
// 详情展开D6异常下挂一个详情子项显示已加载摘要多行
if (!e.detailSummary.empty()) {
auto* detail = new QTreeWidgetItem(item);
detail->setText(0, QString::fromStdString(e.detailSummary));
detail->setFirstColumnSpanned(true);
detail->setForeground(0, geopro::app::tokenColor("text/tertiary"));
}
return item;
}
} // namespace
ObjectExceptionPanel::ObjectExceptionPanel(QWidget* parent) : QWidget(parent) {
auto* lay = new QVBoxLayout(this);
lay->setContentsMargins(0, 0, 0, 0);
lay->setSpacing(0);
tree_ = new QTreeWidget(this);
tree_->setHeaderHidden(true);
tree_->setIndentation(14);
lay->addWidget(tree_, 1);
hint_ = new QLabel(QStringLiteral("(勾选对象后显示其异常 / 异常体)"), this);
hint_->setAlignment(Qt::AlignCenter);
geopro::app::applyTokenizedStyleSheet(hint_, QStringLiteral("color:{{text/disabled}}; padding:16px;"));
lay->addWidget(hint_);
tree_->setVisible(false);
}
void ObjectExceptionPanel::setGroups(
const std::vector<geopro::data::ObjectExceptionGroup>& groups) {
tree_->clear();
bool any = false;
for (const auto& g : groups) {
auto* objItem = new QTreeWidgetItem(tree_);
objItem->setText(0, QString::fromStdString(g.objectName));
for (const auto& c : g.consortia) {
auto* cItem = new QTreeWidgetItem(objItem);
const QString ctype = c.typeName.empty()
? QString()
: QStringLiteral("%1").arg(QString::fromStdString(c.typeName));
cItem->setText(0, QStringLiteral("异常体 %1%2")
.arg(QString::fromStdString(c.name.empty() ? c.id : c.name))
.arg(ctype));
for (const auto& e : c.exceptions) { addException(cItem, e); any = true; }
}
if (!g.looseExceptions.empty()) {
auto* looseItem = new QTreeWidgetItem(objItem);
looseItem->setText(0, QStringLiteral("独立异常(未合并)"));
for (const auto& e : g.looseExceptions) { addException(looseItem, e); any = true; }
}
}
if (!any) {
showMessage(QStringLiteral("(所选对象暂无异常)"));
return;
}
hint_->setVisible(false);
tree_->setVisible(true);
tree_->expandAll();
}
void ObjectExceptionPanel::showMessage(const QString& message) {
tree_->clear();
tree_->setVisible(false);
hint_->setText(message);
hint_->setVisible(true);
}
} // namespace geopro::app

View File

@ -0,0 +1,23 @@
#pragma once
#include <QWidget>
#include <vector>
#include "repo/RepoTypes.hpp"
class QTreeWidget;
class QLabel;
namespace geopro::app {
// 被动:异常 + 异常体 只读树(对象→异常体→异常→详情 + 独立异常)。数据由控制器推送。
class ObjectExceptionPanel : public QWidget {
public:
explicit ObjectExceptionPanel(QWidget* parent = nullptr);
void setGroups(const std::vector<geopro::data::ObjectExceptionGroup>& groups);
void showMessage(const QString& message);
private:
QTreeWidget* tree_ = nullptr;
QLabel* hint_ = nullptr;
};
} // namespace geopro::app