我们在使用qtableview的时候,加载100行的数据,你不会感到有任何卡顿,但是加载百万行的数据,你会感到界面已经卡死,我们来看下效果:
这是我需要加载的一个文件,我们看,共有100万行左右的数据,我们来看下没有优化的写法,及运行时候的效果:
代码:
m_pTestView = new EP_TableView(this);
QStandardItemModel *model = new QStandardItemModel();
m_pTestView->setModel(model);
QVBoxLayout *mainLayout=new QVBoxLayout(this);
mainLayout->addWidget(m_pTestView);
mainLayout->setMargin(0);
mainLayout->setSpacing(0);
this->setLayout(mainLayout);
//加载数据
QFile file("C:/Users/dujia/Desktop/ReceiverTableData.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
int i=0;
while (!file.atEnd()) {
QString strLine=file.readLine();
QStringList strList=strLine.split("&");
model->setItem(i,0,new QStandardItem(strList[0]));
model->setItem(i,1,new QStandardItem(strList[1]));
model->setItem(i,2,new QStandardItem(strList[2]));
model->setItem(i,3,new QStandardItem(strList[3]));
model->setItem(i,4,new QStandardItem(strList[4]));
model->setItem(i,5,new QStandardItem(strList[5]));
model->setItem(i,6,new QStandardItem(strList[6]));
model->setItem(i,7,new QStandardItem(strList[7]));
model->setItem(i,8,new QStandardItem(strList[8]));
model->setItem(i,9,new QStandardItem(strList[9]));
model->setItem(i,10,new QStandardItem(strList[10]));
i=i+1;
}
效果:
当我运行的时候,界面是直接卡死的,可以看到cpu的占用了也很高。
下面开始进行优化,使用多线程,在程序运行时,单独开出一条线程,用来对model数据的加载,
这样会解决卡顿问题,界面也不会迟迟不显示。
直接看代码:
自定义model类
.h
#ifndef STANDARDITEMMODEL_H
#define STANDARDITEMMODEL_H
#include <QObject>
#include <QStandardItemModel>
static const char* DefQSReceiverInfoTableSize[20][3] =
{
{"ID" , "130", "0"},
{"Line" , "110", "0"},
{"Point" , "110", "0"},
{"Index" , "60", "0"},
{"Type" , "60", "0"},
{"X" , "120", "0"},
{"Y" , "120", "0"},
{"Z" , "120", "0"},
{"Lat.-084" , "180", "0"},
{"Long.-084" , "180", "0"},
{"Elav.-84" , "180", "0"},
{"Status" , "100", "0"},
{"Point Depth" , "120", "0"},
{"Water Depth" , "120", "0"},
{"Seis Datum" , "150", "0"},
{" " , "150", "0"},
{" " , "150", "0"},
{" " , "150", "0"},
{" " , "150", "0"}
};
class StandardItemModel : public QStandardItemModel
{
Q_OBJECT
public:
explicit StandardItemModel(QObject *parent = nullptr);
~StandardItemModel();
signals:
public slots:
void CreateData(QString i_path);
};
#endif // STANDARDITEMMODEL_H
.cpp
#include "standarditemmodel.h"
#include <QFile>
#include <QElapsedTimer>
#include <qdebug.h>
StandardItemModel::StandardItemModel(QObject *parent) : QStandardItemModel(parent)
{
this->setColumnCount(15);
for(int i=0;i<15;i++)
{
this->setHeaderData(i, Qt::Horizontal, QString::fromLocal8Bit(DefQSReceiverInfoTableSize[i][0]));
}
}
StandardItemModel::~StandardItemModel()
{
}
//这里用于动态加载数据
void StandardItemModel::CreateData(QString i_path)
{
QFile file(i_path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
int i=0;
while (!file.atEnd()) {
QString strLine=file.readLine();
QStringList strList=strLine.split("&");
this->setItem(i,0,new QStandardItem(strList[0]));
this->setItem(i,1,new QStandardItem(strList[1]));
this->setItem(i,2,new QStandardItem(strList[2]));
this->setItem(i,3,new QStandardItem(strList[3]));
this->setItem(i,4,new QStandardItem(strList[4]));
this->setItem(i,5,new QStandardItem(strList[5]));
this->setItem(i,6,new QStandardItem(strList[6]));
this->setItem(i,7,new QStandardItem(strList[7]));
this->setItem(i,8,new QStandardItem(strList[8]));
this->setItem(i,9,new QStandardItem(strList[9]));
this->setItem(i,10,new QStandardItem(strList[10]));
i=i+1;
}
qDebug()<<"i::"<<i;
qDebug()<<"this:::"<<this->rowCount();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "ep_tableview.h"
#include <QTableWidget>
#include <QThread>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void Start();
signals:
void startRunning(QString);
private:
EP_TableView *m_pTestView=nullptr;
QThread m_thread;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ep_tableview.h"
#include <QStandardItemModel>
#include <QFile>
#include <QVBoxLayout>
#include <QElapsedTimer>
#include <QDebug>
#include <QScrollBar>
#include <QHeaderView>
#include "standarditemmodel.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->resize(800,500);
QFont textFont;
textFont.setPointSize(12);
textFont.setFamily("Microsoft YaHei");
m_pTestView = new EP_TableView(this);
//------------------------thread
StandardItemModel *model = new StandardItemModel();
model->moveToThread(&m_thread);
connect(this,&Widget::startRunning,model,&StandardItemModel::CreateData);
connect(&m_thread,&QThread::finished,model,&QObject::deleteLater);
m_thread.start();
//-----------------------
m_pTestView->setFont(textFont);
m_pTestView->setModel(model);
QVBoxLayout *mainLayout=new QVBoxLayout(this);
mainLayout->addWidget(m_pTestView);
mainLayout->setMargin(0);
mainLayout->setSpacing(0);
this->setLayout(mainLayout);
// QFile file("C:/Users/dujia/Desktop/ReceiverTableData.txt");
// if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
// return;
// int i=0;
// while (!file.atEnd()) {
// QString strLine=file.readLine();
// QStringList strList=strLine.split("&");
// model->setItem(i,0,new QStandardItem(strList[0]));
// model->setItem(i,1,new QStandardItem(strList[1]));
// model->setItem(i,2,new QStandardItem(strList[2]));
// model->setItem(i,3,new QStandardItem(strList[3]));
// model->setItem(i,4,new QStandardItem(strList[4]));
// model->setItem(i,5,new QStandardItem(strList[5]));
// model->setItem(i,6,new QStandardItem(strList[6]));
// model->setItem(i,7,new QStandardItem(strList[7]));
// model->setItem(i,8,new QStandardItem(strList[8]));
// model->setItem(i,9,new QStandardItem(strList[9]));
// model->setItem(i,10,new QStandardItem(strList[10]));
// i=i+1;
// }
}
Widget::~Widget()
{
m_thread.quit();
m_thread.wait();
}
void Widget::Start()
{
emit startRunning("C:/Users/dujia/Desktop/ReceiverTableData.txt");
}
//数据文件的话自己随便一个就可以
看下优化后的运行:
我们看到数据显示出来,并且在实时的的加载。