自定义table model刷新数据效率低(首次很快)

dearbub 2018-04-26 09:31:18
如题!!!首次10000*10仅20毫秒就能刷新,但第二次开始需要9秒左右才行,这是为什么?
#ifndef QMYTABLEMODEL_H
#define QMYTABLEMODEL_H

#include <QAbstractTableModel>
#include <QList>
#include <QHash>

#define Col_Count 10

typedef QHash<int,QVariant> Hash_DataRole;
typedef QList<Hash_DataRole> List_Cols ;
typedef QList<List_Cols> List_Rows ;

class QMyTableModel : public QAbstractTableModel
{
public:
explicit QMyTableModel(QObject *parent = 0);

int setDataSrc(const List_Rows &src,int row, int col);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;

private:
/** 行 列 Qt::ItemDataRole */
List_Rows m_listData;
int m_iRow;
int m_iCol;

};

#endif // QMYTABLEMODEL_H


#include "QMyTableModel.h"

QMyTableModel::QMyTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
m_listData.clear();
m_iRow = 0;
m_iCol = 0;
}

int QMyTableModel::setDataSrc(const List_Rows &src, int row, int col)
{
if(row < 0 || col < 0)
return -1;

m_listData = src;
m_iRow = row;
m_iCol = col;
beginResetModel();
endResetModel();

return m_listData.size();
}

int QMyTableModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_iRow;
}

int QMyTableModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : m_iCol;
}

Qt::ItemFlags QMyTableModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
if(index.isValid())
flags |= (Qt::ItemIsSelectable | Qt::ItemIsEnabled/* | Qt::ItemIsEditable*/);
return flags;
}

QVariant QMyTableModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
int col = index.column();
if(!index.isValid()
|| row < 0 || col < 0 || row > m_iRow-1 || col > m_iCol-1)
return QVariant();
if(row > m_listData.size()-1)
return QVariant();
List_Cols listCols = m_listData.at(row);
if(col > listCols.size()-1)
return QVariant();
Hash_DataRole hashDataRole = listCols.at(col);
if(hashDataRole.contains(role))
return hashDataRole.value(role);
return QVariant();
}


以上为自定义的model,定义model:
m_pModel = new QMyTableModel(this);
ui->tableView->setModel(m_pModel);

使用setDataSrc进行数据的更新:
int row = ui->row->text().toInt();
int col = ui->col->text().toInt();

List_Rows listRows;
for(int i = 0 ; i < row ; ++i)
{
List_Cols listCols;
for(int j = 0; j < col; ++j)
{
Hash_DataRole hashDataRole;
hashDataRole.insert((int)Qt::DisplayRole,QString("%1-%2").arg(i).arg(j));

listCols.push_back(hashDataRole);
}
listRows.push_back(listCols);
}

QTime time;
time.start();
m_pModel->setDataSrc(listRows,row,col);
ui->elapsed->setText(QString("%1 ms").arg(time.elapsed()));

...全文
1994 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
dearbub 2018-05-09
  • 打赏
  • 举报
回复
引用 3 楼 czyt1988 的回复:
从你写的套路上基本没太大问题,就是像1#所说的, beginResetModel();应该放到上面。另外,我看你计时是记录了setDataSrc的耗时,如果这个耗时9秒,你可以在setDataSrc这个函数里逐句分析。 另外感觉你的List_Rows略复杂,不知道是怎么个数据结构,感觉是QList<QList<QHash<int,QVariant>>>的数据结构,如果是这样的话,感觉和QStandardItem区别不大了 ps:计时可以用QElapsedTimer
对的,目的就是想要模仿一个standarmitemmodel,但应该把list在外部处理,不应该反复的引用传递,丢个指针进去就可以了
dearbub 2018-05-09
  • 打赏
  • 举报
回复
引用 1 楼 Marcelxx 的回复:
m_listData = src; m_iRow = row; m_iCol = col; beginResetModel(); endResetModel(); 改为 beginResetModel(); m_listData = src; m_iRow = row; m_iCol = col; endResetModel(); 试试?
试过了,本质没什么区别,主要耗时在容器的传递上
dearbub 2018-05-09
  • 打赏
  • 举报
回复
引用 2 楼 wvjy_001 的回复:
data()实现: 按需要获取的数据role来刷新数据。可以减少data里对数据的操作次数。 /* if(role == Qt::DisplayRole) { var = 你的数据源 } else{ …… } -------------------------------------------------------- if(hashDataRole.contains(role)) return hashDataRole.value(role); 可以用 return hasDataRole.value(role,QVariant());代替。
实际要想大幅度提升效率,应该是在外部处理数据,然后传递一个指针到模型中,调用空的begin和end来出发data的刷新
尘中远 2018-04-30
  • 打赏
  • 举报
回复
从你写的套路上基本没太大问题,就是像1#所说的, beginResetModel();应该放到上面。另外,我看你计时是记录了setDataSrc的耗时,如果这个耗时9秒,你可以在setDataSrc这个函数里逐句分析。 另外感觉你的List_Rows略复杂,不知道是怎么个数据结构,感觉是QList<QList<QHash<int,QVariant>>>的数据结构,如果是这样的话,感觉和QStandardItem区别不大了 ps:计时可以用QElapsedTimer
萝布菜 2018-04-28
  • 打赏
  • 举报
回复
data()实现: 按需要获取的数据role来刷新数据。可以减少data里对数据的操作次数。 /* if(role == Qt::DisplayRole) { var = 你的数据源 } else{ …… } -------------------------------------------------------- if(hashDataRole.contains(role)) return hashDataRole.value(role); 可以用 return hasDataRole.value(role,QVariant());代替。
Marcelxx 2018-04-28
  • 打赏
  • 举报
回复
m_listData = src; m_iRow = row; m_iCol = col; beginResetModel(); endResetModel(); 改为 beginResetModel(); m_listData = src; m_iRow = row; m_iCol = col; endResetModel(); 试试?

16,240

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧