您现在的位置是:首页 >技术教程 >QtableWidget插入数据卡顿优化方法网站首页技术教程

QtableWidget插入数据卡顿优化方法

bclshuai 2023-05-14 16:16:18
简介QtableWidget插入数据卡顿优化方法

最近要使用Qtablewidget保存4300多的数据,发现以下刷新4300条数据,界面会变得非常卡顿,于是想了优化一下;因为要对所有数据排序,想用一下Qtablewidget自动排序功能,而且数据量不多,不想采用动态加载的方式来实现;

方法1复用内存,不重复清除创建

以前每次都会清除,然后重新创建对象,写数据,发现重新pIterm = new QTableWidgetItem;非常耗时,导致界面卡顿;于是想复用已经创建的QTableWidgetItem,插入数据时,先获取Qtablewidget的item,直接在上面写数据;发现速度快了很多;

void QStockView::SlotUpdateHisDataTable(map<QString, HisAnalyzeInfo>& mapHisAnalyze)
{
    m_bUpdatingHisTable = true;
    //ui.tableWidgetHis->setUpdatesEnabled(false);
    //删除内容
    int RowCount = ui.tableWidgetHis->rowCount();
    /*while (rownum > 0)//删除重新插入比较耗时
    {
        ui.tableWidgetHis->removeRow(0);
        rownum--;
    }*/
    //ui.tableWidgetHis->setColumnCount(10);
    map<QString, HisAnalyzeInfo>::iterator it = mapHisAnalyze.begin();
    QTableWidgetItem* pIterm = NULL;
    
    int rownum = 0;
    //先插入已经存在的

    for (;it!= mapHisAnalyze.end();it++)
    {
        int colum = 0;
        if (RowCount>0)
        {
            //第0行是复选框,从1开始
            ui.tableWidgetHis->setRowHidden(rownum, false);
            colum = 1;
            pIterm = ui.tableWidgetHis->item(rownum,colum++);//代码
            if (pIterm != NULL)
            {
                QString strStockCode = it->second.strCode;
                strStockCode = strStockCode.right(6);
                pIterm->setText(strStockCode);
            }
            RowCount--;//可用行数减一
            
        }
        else//插入新的数据
        {

            ui.tableWidgetHis->insertRow(rownum);
            /*QCheckBox* pCheckBox = new QCheckBox();
            pCheckBox->setFixedWidth(20);
            pCheckBox->setChecked(false);
            ui.tableWidgetHis->setCellWidget(rownum, colum++, pCheckBox);*/
            pIterm = new QTableWidgetItem;
            pIterm->setCheckState(Qt::Unchecked);
            ui.tableWidgetHis->setItem(rownum, colum++, pIterm);
            pIterm = new QTableWidgetItem;
            if (pIterm != NULL)
            {
                QString strStockCode = it->second.strCode;
                strStockCode = strStockCode.right(6);
                pIterm->setText(strStockCode);
            }
        }
        rownum++;
    }
    if (RowCount > 0)//隐藏多余的行
    {
        for (int i=0;i<RowCount;i++)
        {
            ui.tableWidgetHis->setRowHidden(rownum+i,true);
        }
    }
    //Slotsortbyclounm(m_sortCloum);//隐藏和排序同时使用时会导致错乱,Qtablewidget->setRowHidden()将无效该隐藏的行没有隐藏;,所以这里注释掉 m_bUpdatingHisTable = false; }

(2)经过上述方法发现,当数据量是4000多时,虽然复用了内存空间,重新刷新一次也要十几秒的时间,而且界面会卡住无响应

原因竟然是第一列采用QCheckBox* pCheckBox = new QCheckBox();插入的复选框,导致刷新数据会非常卡,换成了QTableWidgetItem(pIterm = new QTableWidgetItem; pIterm->setCheckState(Qt::Unchecked))自带的checkbox功能后,用统一的QTableWidgetItem去写数据,不用自定义的widget去设置,速度会很快,4000多条数据1秒之后就加载完成,非常快。也不卡;

 遇到的问题

Qtablewidget->setRowHidden()之后紧跟排序Slotsortbyclounm(m_sortCloum),setRowHidden()将会无效,导致无法隐藏想要隐藏的行;可以考虑用信号槽去关联,或者等到隐藏结束,竖向滚动条的范围发生改变时,再去排序;
Slotsortbyclounm(m_sortCloum);//隐藏和排序同时使用时会导致错乱,Qtablewidget->setRowHidden()将无效该隐藏的行没有隐藏;,所以这里注释掉 m_bUpdatingHisTable = false; }

 如果对软件感兴趣,可维新共总好:QStockView 获取;

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。