Qt5中表格处理大数据量

admin 2022年9月15日10:49:21评论42 views字数 4621阅读15分24秒阅读模式
在Qt中如果是普通项目,GUI处理展现的数据量不大,一般用QTableWidget,QTreeWidget这样的控件就满足了,但是如果数据量行数达到了几万行,那么Widget的展示性能就偏差了。
Qt中提供了一种Model/View的编程方式来处理数据,也就是展示层和数据层分离,这样就解耦了。一旦Model的状态改变,它会自动渲染到View控件。这样的机制使得GUI可以展现大量的数据也不会卡顿。
为了处理数据的灵活性,我们用QStandardItemModel来做QTableView的Model层实现。因为以Table的形式展现,所以以下代码实现了,点击表头按列排序,点击行显式行的上下文菜单的功能。因为QTableView的默认
排序是按字符序列排序,所以得对QStandardItem进行子类化,并重载operator< 函数才能达到某些列用数值大小来排序。
因为是简单的Demo例子,QTableView是采用拖拽空间的方式拖到一个Widget里面的,该Wdiget类为ModelViewTable:
// ModelViewTable.h#pragma once
#include #include "ui_ModelViewTable.h"
class QStandardItemModel;class QMenu;
class ModelViewTable : public QWidget{ Q_OBJECT
public: ModelViewTable(QWidget *parent = Q_NULLPTR); void generateDataSet(); void addRowRecord(int row);
void setColumnItem(int row, int column, QString ip);
public slots: void slotShowContextMenu(const QPoint& point);private: Ui::ModelViewTableClass ui; QStandardItemModel * m_model; QMenu* m_contextMenu;};
// ModelViewTable.cpp#include "ModelViewTable.h"
#include #include #include #include #include
#include "CustomStandardItem.h"
ModelViewTable::ModelViewTable(QWidget *parent) : QWidget(parent){ ui.setupUi(this);
//////////////////////////设置表头///////////////////// m_model = new QStandardItemModel(this); m_model->setColumnCount(3); m_model->setHeaderData(0, Qt::Horizontal, QStringLiteral("终端IP")); m_model->setHeaderData(1, Qt::Horizontal, QStringLiteral("CPU使用率")); m_model->setHeaderData(2, Qt::Horizontal, QStringLiteral("内存使用率"));
ui.tableView->resizeColumnsToContents(); // 自适应列宽 ui.tableView->setSortingEnabled(true); // 可以按列来排序 ui.tableView->setModel(m_model); ui.tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter); ui.tableView->horizontalHeader()->setFont(QFont("Times",10,QFont::Bold));
ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中 ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);// 表格单元格为只读 ui.tableView->setContextMenuPolicy(Qt::CustomContextMenu); // 可以自定义右键菜单
m_contextMenu = new QMenu(this); QAction *processAct = new QAction(QStringLiteral("进程列表信息"),m_contextMenu); QAction *windowAppsAct = new QAction(QStringLiteral("窗口应用列表信息"),m_contextMenu); m_contextMenu->addAction(processAct); m_contextMenu->addAction(windowAppsAct);
connect(ui.tableView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotShowContextMenu(const QPoint&)));

}
void ModelViewTable::generateDataSet(){ for (int i = 0; i < 3000; ++i) { addRowRecord(i); }}
void ModelViewTable::addRowRecord(int row){ // 每行3列 QString ip = QString("%1.%2.%3.%4").arg(192).arg(168).arg(1).arg(row); setColumnItem(row, 0, ip);
QString cpu = QString("%1").arg((row * 10) % 100); setColumnItem(row, 1, cpu);
QString mem = QString("%1").arg((row * 12) % 100); setColumnItem(row, 2, mem);
}
void ModelViewTable::slotShowContextMenu(const QPoint& point){ QModelIndex index = ui.tableView->indexAt(point); if (index.isValid()) { m_contextMenu->exec(QCursor::pos()); }}
void ModelViewTable::setColumnItem(int row, int column, QString ip){ m_model->setItem(row, column, new CustomStandardItem(ip)); m_model->item(row, column)->setTextAlignment(Qt::AlignCenter);}
因为需要实现自定义的数值排序,所以要继承QStandardItem,并覆盖其中的相关函数:
//   CustomStandardItem.h#pragma once
#include #include
// 自定义数值排序class CustomStandardItem : public QStandardItem{ // Q_OBJECT
public: CustomStandardItem(); CustomStandardItem(const CustomStandardItem& other); CustomStandardItem(const QString &text); CustomStandardItem & operator =(const CustomStandardItem& other); ~CustomStandardItem();
public: virtual bool operator<(const QStandardItem& other) const override;
};
//CustomStandardItem.cpp#include "CustomStandardItem.h"
#include
CustomStandardItem::CustomStandardItem(){}
CustomStandardItem::CustomStandardItem(const CustomStandardItem& other) :QStandardItem(other){
}
CustomStandardItem::CustomStandardItem(const QString &text) :QStandardItem(text){
}
CustomStandardItem::~CustomStandardItem(){}
CustomStandardItem & CustomStandardItem::operator=(const CustomStandardItem& other){ QStandardItem::operator=(other); return *this;}
bool CustomStandardItem::operator<(const QStandardItem& other) const{ const QVariant left = data(Qt::DisplayRole), right = other.data(Qt::DisplayRole); // 第1到2列,全部采用浮点数的大小排序 if (column() == other.column() && other.column() >= 1 && other.column() <= 2) { return left.toDouble() < right.toDouble(); }
return QStandardItem::operator<(other);}
以上代码就完全实现了Model/View 的Table编程。
references:
https://stackoverflow.com/questions/18421603/displaying-big-data-using-qt-table-view
https://stackoverflow.com/questions/4031168/qtableview-is-extremely-slow-even-for-only-3000-rows
https://doc.qt.io/archives/qq/qq07-big-tables.html
http://blog.csdn.net/woshiwlia/article/details/9141065
http://blog.csdn.net/u013255206/article/details/62235052
http://qimo601.iteye.com/blog/1539147
http://qimo601.iteye.com/blog/1530539
http://qimo601.iteye.com/blog/1530245

Qt5中表格处理大数据量

原文始发于微信公众号(汇编语言):Qt5中表格处理大数据量

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月15日10:49:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Qt5中表格处理大数据量http://cn-sec.com/archives/1296927.html

发表评论

匿名网友 填写信息