qtableiwdget优化之再优化(大批量数据加载不卡顿)

这篇博客介绍了如何优化QTableWidget以处理大数据,通过自定义滚动条实现分页加载,减少内存占用。作者提到虽然读取大数据文件会导致内存增加,但未使用内存映射技术。文章提供了自定义ScrollBar和TableWidget的代码实现,通过滚动条信号触发数据的加载和卸载,从而在滑动时保持内存稳定。测试数据显示,处理70万行数据约占用200MB内存。
摘要由CSDN通过智能技术生成

前面已经写过2篇关于qtableiwdget的优化的内容了,有感兴趣的可以访问我的主页进行查看,但前面写的或多或少都存在一些问题。
这次写的相对于前面2次优化性能有所提升,并且功能更完善,但有一个问题始终无法避免,就是你把你的大数据文件读入内存中,内存是肯定会增大的。当然,你可以使用qt的内存映射来解决此问题,本篇文章,博主并没有使用内存映射。顺便简介下,内存映射就是把你的硬盘当做内存。
话不多说,直接看代码吧:
自定义scrollbar
scrollbar.h:

#ifndef SCROLLBAR_H
#define SCROLLBAR_H

#include <QWidget>
#include <qscrollbar.h>

class ScrollBar : public QScrollBar
{
    Q_OBJECT
public:
    explicit ScrollBar(QWidget *parent = nullptr);

protected:
    void mouseReleaseEvent(QMouseEvent *e);

signals:
    void sSendValue(float);

public slots:
    void onValueChanged(int i_value);

private:
    float m_Value;
};

#endif // SCROLLBAR_H

scrollbar.cpp
#include "scrollbar.h"

ScrollBar::ScrollBar(QWidget *parent) : QScrollBar(parent)
{
    this->setOrientation(Qt::Vertical);
    connect(this,&QScrollBar::valueChanged,this,&ScrollBar::onValueChanged);
}
void ScrollBar::mouseReleaseEvent(QMouseEvent *e)
{
    emit sSendValue(m_Value);
}

void ScrollBar::onValueChanged(int i_value)
{
    m_Value=float(i_value)/float(this->maximum()); //比例
}

自定义tablewidget:
tablewidget.h

#ifndef TABLEWIDGET_H
#define TABLEWIDGET_H

#include <QWidget>
#include <QTableWidget>
#include "scrollbar.h"

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 TableWidget : public QTableWidget
{
    Q_OBJECT
public:
    explicit TableWidget(QWidget *parent = nullptr);
    ~TableWidget();

    void CreateFirstData();

    void ClearAllRow();

    void DownLoadData();
    void UpLoadData();

protected:
    void wheelEvent(QWheelEvent *event);

signals:

public slots:
    void onValueChanged(float i_value);
private:
     QList<QByteArray> m_strList;
     QList<QByteArray> m_strFirstList;

     int m_CurrentRow=0;

     int m_Size=0;

     ScrollBar *m_pScrollBar=nullptr;
};

#endif // TABLEWIDGET_H

tablewidget.cpp

#include "tablewidget.h"
#include <QFile>
#include <qdebug.h>
#include <QScrollBar>
#include <QWheelEvent>

TableWidget::TableWidget(QWidget *parent) : QTableWidget(parent)
{
    this->setColumnCount(15);
    QStringList headerList;
    for(int i=0;i<15;i++)
    {
        headerList.append(QString::fromLocal8Bit(DefQSReceiverInfoTableSize[i][0]));
    }
    this->setHorizontalHeaderLabels(headerList);

    m_pScrollBar=new ScrollBar(this);
    this->setVerticalScrollBar(m_pScrollBar);

    connect(m_pScrollBar,&ScrollBar::sSendValue,this,&TableWidget::onValueChanged);

    QFile file("C:/Users/dujia/Desktop/aaa.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;

    while (!file.atEnd()) {
        QByteArray line = file.readLine();
        m_strList.append(line);
        if(m_strList.size()==500)
        {
            m_strFirstList=m_strList;
            m_Size=m_strFirstList.size();
            CreateFirstData();
        }
    }

    qDebug()<<"scrollbar::"<<this->verticalScrollBar()->maximum();
}

TableWidget::~TableWidget()
{

}

void TableWidget::CreateFirstData()
{
    if(m_strFirstList.size()!=0)
    {
        this->setRowCount(m_strFirstList.size());
        for(int i=0;i<m_strFirstList.size();i++)
        {
            QString str=m_strFirstList[i];
            QStringList strList=str.split("&");
            this->setItem(i,0,new QTableWidgetItem(strList[0]));
            this->setItem(i,1,new QTableWidgetItem(strList[1]));
            this->setItem(i,2,new QTableWidgetItem(strList[2]));
            this->setItem(i,3,new QTableWidgetItem(strList[3]));
            this->setItem(i,4,new QTableWidgetItem(strList[4]));
            this->setItem(i,5,new QTableWidgetItem(strList[5]));
            this->setItem(i,6,new QTableWidgetItem(strList[6]));
            this->setItem(i,7,new QTableWidgetItem(strList[7]));
            this->setItem(i,8,new QTableWidgetItem(strList[8]));
            this->setItem(i,9,new QTableWidgetItem(strList[9]));
            this->setItem(i,10,new QTableWidgetItem(strList[10]));
        }
    }


}

void TableWidget::ClearAllRow()
{
    for(int i=this->rowCount();i>=0;i--)
    {
        this->removeRow(i);
    }
}

void TableWidget::DownLoadData()
{
    this->setRowCount(500);
    int K=0;
    for(int i=m_CurrentRow;i<m_CurrentRow+500;i++)
    {
        QString str=m_strList[i];
        QStringList strList=str.split("&");
        this->setItem(K,0,new QTableWidgetItem(strList[0]));
        this->setItem(K,1,new QTableWidgetItem(strList[1]));
        this->setItem(K,2,new QTableWidgetItem(strList[2]));
        this->setItem(K,3,new QTableWidgetItem(strList[3]));
        this->setItem(K,4,new QTableWidgetItem(strList[4]));
        this->setItem(K,5,new QTableWidgetItem(strList[5]));
        this->setItem(K,6,new QTableWidgetItem(strList[6]));
        this->setItem(K,7,new QTableWidgetItem(strList[7]));
        this->setItem(K,8,new QTableWidgetItem(strList[8]));
        this->setItem(K,9,new QTableWidgetItem(strList[9]));
        this->setItem(K,10,new QTableWidgetItem(strList[10]));
        K=K+1;
    }
}

void TableWidget::UpLoadData()
{
    this->setRowCount(500);
    int K=0;
    for(int i=m_CurrentRow;i<m_CurrentRow+500;i++)
    {
        QString str=m_strList[i];
        QStringList strList=str.split("&");
        this->setItem(K,0,new QTableWidgetItem(strList[0]));
        this->setItem(K,1,new QTableWidgetItem(strList[1]));
        this->setItem(K,2,new QTableWidgetItem(strList[2]));
        this->setItem(K,3,new QTableWidgetItem(strList[3]));
        this->setItem(K,4,new QTableWidgetItem(strList[4]));
        this->setItem(K,5,new QTableWidgetItem(strList[5]));
        this->setItem(K,6,new QTableWidgetItem(strList[6]));
        this->setItem(K,7,new QTableWidgetItem(strList[7]));
        this->setItem(K,8,new QTableWidgetItem(strList[8]));
        this->setItem(K,9,new QTableWidgetItem(strList[9]));
        this->setItem(K,10,new QTableWidgetItem(strList[10]));
        K=K+1;
    }
}

void TableWidget::wheelEvent(QWheelEvent *event)
{
    int delta= event->delta();
    if(delta>0)
    {
        if(m_CurrentRow!=0)
        {
            ClearAllRow();
            m_CurrentRow=m_CurrentRow-5;

            UpLoadData();

            float Value=float(m_CurrentRow)/float(m_strList.size());
            float currentValue=Value*this->verticalScrollBar()->maximum();
            this->verticalScrollBar()->setValue(currentValue);

        }
    }
    else
    {
        if(m_CurrentRow<m_strList.size()-500)
        {
            m_CurrentRow=m_CurrentRow+5;

            ClearAllRow();

            DownLoadData();

            float Value=float(m_CurrentRow)/float(m_strList.size());
            float currentValue=Value*this->verticalScrollBar()->maximum();
            this->verticalScrollBar()->setValue(currentValue);
        }
    }
}

void TableWidget::onValueChanged(float i_value)
{
    m_CurrentRow=i_value*(m_strList.size()-500);

    ClearAllRow();
    int K=0;
    this->setRowCount(500);
    for(int i=m_CurrentRow;i<m_CurrentRow+500;i++)
    {
        QString str=m_strList[i];
        QStringList strList=str.split("&");
        this->setItem(K,0,new QTableWidgetItem(strList[0]));
        this->setItem(K,1,new QTableWidgetItem(strList[1]));
        this->setItem(K,2,new QTableWidgetItem(strList[2]));
        this->setItem(K,3,new QTableWidgetItem(strList[3]));
        this->setItem(K,4,new QTableWidgetItem(strList[4]));
        this->setItem(K,5,new QTableWidgetItem(strList[5]));
        this->setItem(K,6,new QTableWidgetItem(strList[6]));
        this->setItem(K,7,new QTableWidgetItem(strList[7]));
        this->setItem(K,8,new QTableWidgetItem(strList[8]));
        this->setItem(K,9,new QTableWidgetItem(strList[9]));
        this->setItem(K,10,new QTableWidgetItem(strList[10]));
        K=K+1;
    }
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "tablewidget.h"



class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:


    TableWidget *m_pTableWgt=nullptr;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include <QFile>
#include <qdebug.h>
#include <QVBoxLayout>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(800,500);

    m_pTableWgt=new TableWidget(this);
    QVBoxLayout *mainLayout=new QVBoxLayout(this);
    mainLayout->addWidget(m_pTableWgt);
    mainLayout->setMargin(0);
    this->setLayout(mainLayout);


}

Widget::~Widget()
{
}


我测试的数据是70万行左右的数据,会吃掉200mb左右的内存。这个应该是正常的。文件大小80mb。通过文本文件打开,大概180mb左右
在这里插入图片描述
在滑动的时候,内存是不会改变的。

我给出我tablewidget的格式,然后复制到记事本,复制粘贴就行。

1512058602&   2884.00&  12010.00  &1&G1& 644347.8& 4229422.2&3123.7&38 12 04.281 N&076 38 54.825 E&3123.70&    &    &&
1512058603&   2884.00&  12011.00  &1&G1& 644357.8& 4229439.4&3123.8&38 12 04.833 N&076 38 55.249 E&3123.80&    &    &&
1512058604&   2884.00&  12012.00  &1&G1& 644367.7& 4229456.9&3123.1&38 12 05.395 N&076 38 55.669 E&3123.10&    &    &&
1512058605&   2884.00&  12013.00  &1&G1& 644377.8& 4229474.1&3124.3&38 12 05.947 N&076 38 56.096 E&3124.30&    &    &&
1512058606&   2884.00&  12014.00  &1&G1& 644387.7& 4229491.4&3125.6&38 12 06.502 N&076 38 56.516 E&3125.60&    &    &&
1512058607&   2884.00&  12015.00  &1&G1& 644397.7& 4229508.8&3125.3&38 12 07.061 N&076 38 56.940 E&3125.30&    &    &&
1512058608&   2884.00&  12016.00  &1&G1& 644407.7& 4229526.0&3125.4&38 12 07.613 N&076 38 57.363 E&3125.40&    &    &&
1512058609&   2884.00&  12017.00  &1&G1& 644417.7& 4229543.4&3125.7&38 12 08.171 N&076 38 57.787 E&3125.70&    &    &&

ヾ( ̄▽ ̄)ByeBye

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油小杜(接qt定制功能,单模块开发等)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值