modified tablepanel

This commit is contained in:
pimin 2025-10-27 17:48:27 +08:00
parent fafd290244
commit 863e0867ce
9 changed files with 401 additions and 79 deletions

View File

@ -11,8 +11,6 @@
#include <QCheckBox>
#include <QHBoxLayout>
#include "ui_FitCurve.h"
CurvePanel::CurvePanel(int index, const QString& filePath, QWidget* parent)
: DataPanel(index, FileEntryType::Curve, filePath, parent)
{

View File

@ -5,9 +5,6 @@
#include <memory>
#include "ui/chartPlot/FitCurveChartView.h"
namespace Ui {
class FitCurve;
}
/**
* @file CurvePanel.h
* @brief Curve Panel Class
@ -92,13 +89,9 @@ private:
void updateReportData(double t);
private:
Ui::FitCurve* ui;
FitCurveChartView* curveChartView;
QChart* curveChart;
bool isPressed = false;
QPoint pressedPoint;
QValueAxis* m_pAxisX = NULL;
QValueAxis* m_pAxisY = NULL;
float m_iXMax;

View File

@ -5,7 +5,7 @@
// Forward declarations for future panel types
// #include "SurfacePanel.h"
// #include "TablePanel.h"
#include "TablePanel.h"
// #include "LightPanel.h"
DataPanel* DataPanelFactory::CreatePanel(FileEntryType fileType, int index, const QString& filePath, QWidget* parent)
@ -24,7 +24,7 @@ DataPanel* DataPanelFactory::CreatePanel(FileEntryType fileType, int index, cons
case FileEntryType::Table:
// TODO: Implement TablePanel
LOG_WARN("TablePanel not implemented yet, creating base DataPanel");
return new DataPanel(index, fileType, filePath, parent);
return new TablePanel(index, filePath, parent);
case FileEntryType::Light:
// TODO: Implement LightPanel

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FitCurve</class>
<widget class="QDialog" name="FitCurve">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>977</width>
<height>703</height>
</rect>
</property>
<property name="windowTitle">
<string>FitCurveDialog</string>
</property>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>70</x>
<y>40</y>
<width>851</width>
<height>621</height>
</rect>
</property>
<layout class="QHBoxLayout" name="chartLayout"/>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

224
src/ui/Panel/TablePanel.cpp Normal file
View File

@ -0,0 +1,224 @@
#include "ui/Panel/TablePanel.h"
#include "ui/DockWidget.h"
#include "ui/DockTitleBar.h"
#include "common/SpdLogger.h"
#include <QHBoxLayout>
#include <QFileInfo>
#include <QMessageBox>
#include <QHeaderView>
TablePanel::TablePanel(int index, const QString& filePath, QWidget* parent)
: DataPanel(index, FileEntryType::Curve, filePath, parent)
{
LOG_INFO("Created TablePanel {} for file: {}", index, filePath.toStdString());
}
TablePanel::TablePanel(int index, std::shared_ptr<FileEntryTable> fileEntry, QWidget* parent)
: DataPanel(index, fileEntry, parent)
{
if (fileEntry) {
LOG_INFO("Created TablePanel {} for chart: {}", index, fileEntry->GetName().toStdString());
// Override the title with chart name
title_ = QString("Table Panel %1 - %2").arg(index).arg(fileEntry->GetName());
}
else {
LOG_WARN("Created TablePanel {} with null chart data", index);
}
}
TablePanel::~TablePanel()
{
LOG_INFO("Destroyed TablePanel {}", GetIndex());
}
void TablePanel::RefreshPanel()
{
// Implement curve-specific refresh logic here
DataPanel::RefreshPanel();
if (auto fileEntry = fileEntry_->AsTable()) {
OnDataPanelUpdated(fileEntry);
}
LOG_INFO("Refreshed TablePanel {}", GetIndex());
}
void TablePanel::InitUI()
{
m_pTableWidget = new QTableWidget;
QHeaderView* horizontalHeader = m_pTableWidget->horizontalHeader();
QColor headerColor = QColor(100, 100, 100);
horizontalHeader->setStyleSheet(QString("QHeaderView::section {background-color: %1;}").arg(headerColor.name()));
horizontalHeader->setStretchLastSection(true);
m_pTableWidget->verticalHeader()->setHidden(true);
m_pTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pTableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
//m_pTableWidget->setSortingEnabled(true);
//connect(m_pTableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem *)),
// this, SLOT(slotDoubleClickedItem(QTableWidgetItem *)));
//connect(m_pTableWidget, SIGNAL(itemClicked(QTableWidgetItem *)),
// this, SLOT(slotClickedItem(QTableWidgetItem *)));
//connect(m_pTableWidget->horizontalHeader(),SIGNAL(sectionClicked(int)), this, SLOT(slotSortTabCol(int)));
QHBoxLayout* mainLayout = new QHBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(m_pTableWidget);
setLayout(mainLayout);
}
QString TablePanel::GetTypeDisplayName() const
{
return "Table";
}
void TablePanel::OnDataPanelUpdated(FileEntryTable* fileEntry)
{
QString strName = fileEntry->GetName();
updateTitle(strName);
FileEntryTable::ChartProperties propChart = fileEntry->GetChartProperties();
QStringList tableHeader = propChart.headerString.split(',', Qt::SkipEmptyParts);
SetHeader(tableHeader);
QString strFile = fileEntry->GetPath() + "/" + fileEntry->GetFileName();
FileEntryTable::TableProperties listCurve = fileEntry->GetTableProperties();
updateParseFile(strFile, propChart.timeParam, listCurve);
}
void TablePanel::OnTimeChanged(double time)
{
updateTable(time);
}
void TablePanel::updateTitle(const QString & title)
{
if (nullptr != dockWidget_)
{
dockWidget_->setWindowTitle(title);
}
}
void TablePanel::SetHeader(const QStringList& headerLabels)
{
m_pTableWidget->clear();
m_pTableWidget->setColumnCount(headerLabels.size());
m_pTableWidget->setHorizontalHeaderLabels(headerLabels);
}
void TablePanel::updateParseFile(const QString & strFile, int nT, FileEntryTable::TableProperties listCurve)
{
if (strFile.isEmpty())
{
QMessageBox::information(nullptr, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请检查数据文件路径!"));
return;
}
QFile file(strFile);
if (file.open(QIODevice::ReadOnly))
{
for (int nI = 0; nI < listCurve.size(); nI++)
{
FileEntryTable::TableProperty curve = listCurve.at(nI);
m_tableSetting.insert(nI, qMakePair(curve.name, curve.color));
}
while (!file.atEnd())
{
QString strLine = file.readLine().simplified();
if (!strLine.isEmpty())
{
QStringList listLine = strLine.split(" ");
double t = listLine.at(nT).toDouble();
QMap<int, QVariantList> mapData;
if (listCurve.size() == 0)
{
int nCount = m_pTableWidget->columnCount();
int nRow = (listLine.size() - 1) / nCount;
for (int nI = 0; nI < nRow; nI++)
{
int nBegin = nT + 1 + nI * nCount;
QVariantList varList;
for (int nJ = 0; nJ < nCount; nJ++)
{
int nIndex = nBegin + nJ;
double data = listLine.at(nIndex).toDouble();
varList.push_back(data);
}
mapData.insert(nI, varList);
}
}
else
{
for (int nI = 0; nI < listCurve.size(); nI++)
{
FileEntryTable::TableProperty curve = listCurve.at(nI);
QVariantList varList;
for (int nJ = 0; nJ < curve.datas.size(); nJ++)
{
int nIndex = curve.datas.at(nJ);
double data = listLine.at(nIndex).toDouble();
varList.push_back(data);
}
mapData.insert(nI, varList);
}
}
m_dataTable.insert(t, mapData);
}
}
file.close();
}
}
void TablePanel::updateTable(double t)
{
if (m_dataTable.size() > 0)
{
clearTable();
QMap< double, QMap<int, QVariantList> >::const_iterator ite = m_dataTable.lowerBound(t);
if (ite == m_dataTable.end())
{
ite--;
}
QMap<int, QVariantList> mapData = ite.value();
for (QMap<int, QVariantList>::Iterator it = mapData.begin(); it != mapData.end(); it++)
{
int nRow = it.key();
QVariantList dataList = it.value();
m_pTableWidget->insertRow(nRow);
for (int nI = 0; nI < dataList.size(); nI++)
{
QString strVal;
strVal.sprintf("%.6f", dataList.at(nI).toFloat());
QTableWidgetItem *item = new QTableWidgetItem(strVal);
item->setTextAlignment(Qt::AlignCenter);
m_pTableWidget->setItem(nRow, nI, item);
}
}
}
}
void TablePanel::clearTable()
{
int nCount = m_pTableWidget->rowCount();
for (int nI = 0; nI < nCount; )
{
m_pTableWidget->removeRow(0);
nCount = m_pTableWidget->rowCount();
}
}

76
src/ui/Panel/TablePanel.h Normal file
View File

@ -0,0 +1,76 @@
#pragma once
#include "DataPanel.h"
#include "workspace/FileEntry.h"
#include <memory>
#include <QTableWidget>
class TablePanel : public DataPanel
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param index Panel index
* @param filePath Associated file path
* @param parent Parent widget
*/
explicit TablePanel(int index, const QString& filePath, QWidget* parent = nullptr);
/**
* @brief Constructor with chart data
* @param index Panel index
* @param chartData Chart data containing curve information
* @param parent Parent widget
*/
explicit TablePanel(int index, std::shared_ptr<FileEntryTable> fileEntry, QWidget* parent = nullptr);
/**
* @brief Destructor
*/
virtual ~TablePanel();
/**
* @brief Get file type
* @return File type (always Curve for this class)
*/
FileEntryType GetFileType() const override { return FileEntryType::Table; }
/**
* @brief Refresh panel content
*/
void RefreshPanel() override;
protected:
/**
* @brief Initialize UI for curve-specific layout
*/
virtual void InitUI();
/**
* @brief Get type display name
* @return Display name for curve type
*/
QString GetTypeDisplayName() const override;
void OnDataPanelUpdated(FileEntryTable* fileEntry);
virtual void OnTimeChanged(double time);
private:
void updateTitle(const QString& title);
void SetHeader(const QStringList& headerLabels);
void updateParseFile(const QString& strFile, int nT, FileEntryTable::TableProperties listCurve);
void updateTable(double t);
void clearTable();
private:
QTableWidget *m_pTableWidget;
QMap< int, QPair<QString, QColor> > m_tableSetting;
QMap< double, QMap<int, QVariantList> > m_dataTable;
};

View File

@ -134,17 +134,15 @@ void AddTableFileDlg::accept()
for (QString& header : headers) {
header = header.trimmed();
}
fileEntry->SetTableHeaders(headers);
//fileEntry->SetTableHeaders(headers);
}
// Set chart properties
FileEntryTable::ChartProperties chartProps;
chartProps.headerString = headersText;
chartProps.timeParam = ui->timeParamSpinBox->value();
fileEntry->SetChartProperties(chartProps);
// Set description (using table name as description for now)
fileEntry->SetDescription(ui->tableNameEdit->text());
// Add to workspace
WorkSpace* workspace = WorkSpaceManager::Get().GetCurrent();
if (!workspace) {

View File

@ -217,32 +217,104 @@ const FileEntryTable::TableProperties& FileEntryTable::GetTableProperties() cons
return tableProperties_;
}
void FileEntryTable::SetTableHeaders(const QStringList& headers) {
tableHeaders_ = headers;
}
void FileEntryTable::SetTableHeaders(const QString& headerString) {
tableHeaders_ = headerString.split(',', Qt::SkipEmptyParts);
// Trim whitespace from each header
for (QString& header : tableHeaders_) {
header = header.trimmed();
}
}
const QStringList& FileEntryTable::GetTableHeaders() const {
return tableHeaders_;
}
FileEntryTable* FileEntryTable::AsTable() {
return this;
}
void FileEntryTable::SetDescription(const QString& description) {
description_ = description;
bool FileEntryTable::SaveFiles(tinyxml2::XMLElement * scene, tinyxml2::XMLDocument * doc)
{
if (!scene || !doc) {
LOG_ERROR("Invalid XML parameters");
return false;
}
const QString& FileEntryTable::GetDescription() const {
return description_;
// 创建 <chart> 元素
tinyxml2::XMLElement* chartElement = doc->NewElement("chart");
scene->InsertEndChild(chartElement);
// 设置chart属性
chartElement->SetAttribute("name", name_.toUtf8().constData());
chartElement->SetAttribute("path", fileName_.toUtf8().constData());
chartElement->SetAttribute("head", chartProperties_.headerString.toUtf8().constData());
chartElement->SetAttribute("t", chartProperties_.timeParam);
// 为每个CurveProperty创建<curve>元素
for (const auto& curve : tableProperties_) {
tinyxml2::XMLElement* curveElement = doc->NewElement("curve");
chartElement->InsertEndChild(curveElement);
curveElement->SetAttribute("name", curve.name.toUtf8().constData());
curveElement->SetAttribute("color", QColorToString(curve.color).toUtf8().constData());
QString strData = "";
for (int i = 0; i < curve.datas.size(); i++)
{
int nIndex = curve.datas.at(i);
if (strData.isEmpty())
{
strData = QString::number(nIndex);
}
else
{
strData += "," + QString::number(nIndex);
}
}
curveElement->SetAttribute("data", strData.toUtf8().constData());
}
return true;
}
bool FileEntryTable::ParseFiles(const tinyxml2::XMLElement * element)
{
if (!element) {
LOG_ERROR("Invalid XML element");
return false;
}
// 解析chart属性
const char* nameAttr = element->Attribute("name");
const char* pathAttr = element->Attribute("path");
if (nameAttr) name_ = QString::fromUtf8(nameAttr);
if (pathAttr) {
QString fullPath = QString::fromUtf8(pathAttr);
QFileInfo fileInfo(fullPath);
fileName_ = fileInfo.fileName();
path_ = fileInfo.absolutePath();
}
const char* headAttr = element->Attribute("head");
if (headAttr) {
chartProperties_.headerString = QString::fromUtf8(headAttr);
}
chartProperties_.timeParam = element->DoubleAttribute("t", 0.0);
for (const tinyxml2::XMLElement* curveElement = element->FirstChildElement("curve");
curveElement != nullptr;
curveElement = curveElement->NextSiblingElement("curve")) {
TableProperty table;
const char* curveNameAttr = curveElement->Attribute("name");
const char* colorAttr = curveElement->Attribute("color");
if (curveNameAttr) table.name = QString::fromUtf8(curveNameAttr);
if (colorAttr) table.color = StringToQColor(QString::fromUtf8(colorAttr));
const char* dataAttr = curveElement->Attribute("data");
if (dataAttr)
{
QStringList strList = QString::fromUtf8(dataAttr).split(",", Qt::SkipEmptyParts);
for (int i = 0; i < strList.size(); i++)
{
table.datas.push_back(strList.at(i).toInt());
}
}
tableProperties_.append(table);
}
return true;
}
// FileEntryCurve SaveFiles implementation

View File

@ -221,8 +221,7 @@ private:
class FileEntryTable : public FileEntry {
public:
struct ChartProperties {
QString name;
QString path;
QString headerString;
double timeParam;
};
@ -247,23 +246,16 @@ public:
void SetTableProperty(int index, const TableProperty& table);
const TableProperties& GetTableProperties() const;
// Table headers management
void SetTableHeaders(const QStringList& headers);
void SetTableHeaders(const QString& headerString); // Parse from comma-separated string
const QStringList& GetTableHeaders() const;
// Type conversion
FileEntryTable* AsTable() override;
// Description management
void SetDescription(const QString& description);
const QString& GetDescription() const;
// XML处理方法
bool SaveFiles(tinyxml2::XMLElement* scene, tinyxml2::XMLDocument* doc) override;
bool ParseFiles(const tinyxml2::XMLElement* element) override;
private:
ChartProperties chartProperties_;
QStringList tableHeaders_;
TableProperties tableProperties_;
QString description_;
};
class FileEntryLight : public FileEntry {