我想从现有表生成一些简单的group和sum数据计算 并在另一个表/视图上显示结果。 (见图)
我通过重新实现QSortFilterProxyModel成功实现了这一点 我必须覆盖data()函数 并保留我自己的模型数据。
我不确定这是最好的方法,
我读了一些表格,建议为这类任务重新实现QAbstractProxyModel, 但我没有找到任何好的例子。
以下是我实施的部分
模型h文件
#include
typedef struct _TableItem_
{
_TableItem_()
{
}
_TableItem_(const QString& _oName, int _iValue)
{
this->iValue = _iValue;
this->oName = _oName;
}
int iValue;
QString oName;
}STABLE_ITEM;
typedef QVector<STABLE_ITEM> TableData;
// Proxy model for doing group and count
class TableGroupModel : public QSortFilterProxyModel
{
Q_OBJECT
private:
mutable TableData m_oData;
QVariant GetData(int iRow, int iColumn) const;
bool AddItem(const QString & oName, int iValue) const;
protected:
bool filterAcceptsRow(int iSourceRow, const QModelIndex &oSourceParent) const;
QVariant data(const QModelIndex &oIndex, int role) const override;
public:
TableGroupModel(QObject *parent = NULL) ;
void Clear();
};
模型cpp文件
#include "table_group_model.h"
TableGroupModel::TableGroupModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
void TableGroupModel::Clear()
{
m_oData.clear();
}
QVariant TableGroupModel::GetData(int iRow, int iColumn) const
{
switch (iColumn) {
case 0: // Name column
return m_oData.at(iRow).oName;
case 1: // Value column
return m_oData.at(iRow).iValue;
default:
break;
}
return QVariant();
}
bool TableGroupModel::AddItem(const QString &oName, int iValue) const
{
// search for the item.
auto oIt = std::find_if(m_oData.begin(), m_oData.end(),
[oName](const STABLE_ITEM & sTableItem){
return (sTableItem.oName == oName);
});
// Item found ?
if (oIt != m_oData.end())
{
// update values.
(*oIt).iValue += iValue;
// filter this row.
return false;
}
// Append new item
m_oData.append(STABLE_ITEM(oName, iValue));
// accept this row
return true;
}
bool TableGroupModel::filterAcceptsRow(int iSourceRow, const QModelIndex &oSourceParent) const
{
QModelIndex oIndex=
sourceModel()->index(iSourceRow, 0, oSourceParent);
QString oValueName =
sourceModel()->data(oIndex).toString();
oIndex=
sourceModel()->index(iSourceRow, 1, oSourceParent);
int iValue =
sourceModel()->data(oIndex).toInt();
// append data
return AddItem(oValueName, iValue);
}
QVariant TableGroupModel::data(const QModelIndex &oIndex, int role) const
{
if (!oIndex.isValid())
return QVariant();
switch (role) {
case Qt::DisplayRole:
return GetData(oIndex.row(), oIndex.column());
default:
break;
}
return sourceModel()->data(oIndex,role);
}
主窗口cpp
#include "mainwindow.h"
#include <QTableView>
#include <QHBoxLayout>
#include "table_model.h"
#include "table_group_model.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
this->setCentralWidget(InitTableWidget());
// Fill table with data.
FillTable();
}
MainWindow::~MainWindow()
{
}
QWidget *MainWindow::InitTableWidget()
{
QHBoxLayout * poHTableLayout = new QHBoxLayout;
// Table Model
m_poTableModel.reset(new TableModel);
// Table view
QTableView * poTable = new QTableView(this);
poTable->setModel(m_poTableModel.data());
// Group table view
QTableView * poGroupTable = new QTableView(this);
m_poTableGroupModel.reset(new TableGroupModel(this));
m_poTableGroupModel->setSourceModel(m_poTableModel.data());
poGroupTable->setModel(m_poTableGroupModel.data());
// Layout horizontal tables
poHTableLayout->addWidget(poTable);
poHTableLayout->addWidget(poGroupTable);
QWidget * poTablesWidget = new QWidget(this);
poTablesWidget->setLayout(poHTableLayout);
return poTablesWidget;
}
void MainWindow::FillTable()
{
TableData oTableData;
oTableData.append(STABLE_ITEM("a",1));
oTableData.append(STABLE_ITEM("a",2));
oTableData.append(STABLE_ITEM("b",3));
oTableData.append(STABLE_ITEM("c",4));
oTableData.append(STABLE_ITEM("c",5));
oTableData.append(STABLE_ITEM("a",7));
m_poTableModel->DropTable(oTableData);
}
我的GitHub页
中的完整代码有什么建议吗?