• QTableWidget懒加载(动态加载)实现


      在QTableWidget中加入一行行的数据,如果数据数量过多,滚动起来就会卡顿,插入数据时也会影响性能,为了解决这个问题,采用懒加载的方式,只在界面上显示10几条数据,填满界面。同时增加而外的竖直滚动条,控制滚动条滑块的大小,给外界看到的效果就是有随着数据数量的增加,滚动条减小。滚动滚动条,或者插入新数据,都将界面中的数据删除,然后重新刷新一些。而且最新的显示在上面,历史的显示在下面。Vector中是按插入顺序从下排列,table中显示是按照插入顺序从下往上排列。

    (1)      界面上添加QTableWidgetScrollBar

                           

    2)创建vect保存数据的唯一编号,创建map按唯一编号保存数据。

    vector <string> m_vectorLogid;

    map<string,ALARMUIDATA> m_mapRealAlarm;

    vector用来保存数据插入的顺序,而且能够按照数组的形式访问数据,但是查找数据只能遍历整个vecttor,所以不适合查找。因为map是按一定规则排序的,不是按照插入顺序排序的,但是map可以快速查找,需要结合两个实现懒加载。

    3)当需要改变界面中显示的数据时(有新的数据插入时,或者滚动条滚动时,或者界面放大缩小时,删除数据时),都要重新删除表格中数据,在加入数据。

    void AlarmCenter::UpdateAlarmList()

    {

           //不用deleteallitem函数,会连表头都一起删除,deletecontent会保留插入的行框架,所以采用下面的形式删除插入数据。

                  int iAlarmCount = ui.tableWidget->rowCount();//删除现有的row

                  if (iAlarmCount > 0)

                  {

                         for (int i = 0; i < iAlarmCount; i++)

                         {

                                ui.tableWidget->removeRow(0);

                         }

                  }

          

           //计算当前页面可以展示的条数

           int rowHeight = ui.tableWidget->rowHeight(0);

           if (rowHeight == 0)

           {

                  rowHeight = 36;

           }

    //获取tableWidget的显示高度

           int tableViewHeight = ui.tableWidget->height();

    //计算一页可以显示的数据条数

           int pagestep = tableViewHeight / rowHeight-1 ;//1是减去表头的高度

           if (pagestep<0)

           {

                  return;

           }

           //插入数据的总条数

           int iMaxNum = AlarmDataManager::instance()->GetAlarmNum();

    //滑块的当前位置(0开始)

           m_sliderCurPosion = ui.verticalScrollBarAlarm->sliderPosition();

    //根据当前的滑块位置,总的报警数量,一页显示报警数量,开始插入数据

           for (int step =0;step<pagestep;step++)

           {

    //计算vector中的第一条显示的数据,step增加,index值减小,反向在vector中查找数据。

                  int index = iMaxNum - m_sliderCurPosion - step-1;

                  if (index<0|| index>=iMaxNum)//超出范围跳出

                  {

                         break;

                  }

                  ALARMUIDATA alarmData;

    //根据index直接按照数组形式获取唯一标示logid,然后根据logid去map中找数据返回。

                  if (AlarmDataManager::instance()->GetAlarmByIndex(alarmData,index)!=HPR_OK)

                  {

                         LOGIC_ERROR("Can't find alarmdata by index %d", index);

                         continue;

                  }

    //插入一条数据

                  ui.tableWidget->insertRow(step); //插入新行

                  AddAlarmToWidget(alarmData,index,step);

           }

    //总数量大于一页显示数量时,显示滚动条,设置滚动条范围,控制滑块大小

           if (iMaxNum>pagestep)

           {

                  ui.verticalScrollBarAlarm->setMaximum(iMaxNum - pagestep);

                  ui.verticalScrollBarAlarm->show();

                  //LOGIC_INFO("maxnum %d,sliderposion %d", ui.verticalScrollBarAlarm->maximum(),ui.verticalScrollBarAlarm->sliderPosition());

           }

           else

           {

                  ui.verticalScrollBarAlarm->hide();

           }

    }

    4)重写resizeevent函数

    void AlarmCenter::resizeEvent(QResizeEvent* size)

    {

    //一页显示的数量会变化,所以要刷新

           UpdateAlarmList();

    }

    (1)      重写wheelEvent函数

    void AlarmCenter::wheelEvent(QWheelEvent * event)

    {

         if (event->x()>ui.alarmCenter->width())//如果鼠标在右侧窗口上,则不滚动左边报警列表;

         {

                return;

         }

         int tableViewHeight = ui.tableWidget->height();

         int pagestep = tableViewHeight / 36 - 1;//1是减去表头的高度

         //插入数据报警总数

         int iMaxNum = AlarmDataManager::instance()->GetAlarmNum();

         if (iMaxNum<pagestep)//总数小于页面显示数量,则滚动无效

         {

                return;

         }

         if (event->delta() > 0) //向下滚动

         {

                m_sliderCurPosion -= 1;

                if (m_sliderCurPosion < 0)

                {

                       m_sliderCurPosion = 0;

                       return;

                }    

         }

         else///向上滚动

         {

                m_sliderCurPosion += 1;

                if (m_sliderCurPosion > ui.verticalScrollBarAlarm->maximum())

                {

                       m_sliderCurPosion = ui.verticalScrollBarAlarm->maximum();

                       return;

                }

               

         }

         //更新滑块位置

         ui.verticalScrollBarAlarm->setSliderPosition(m_sliderCurPosion);

         //更新表格信息

    UpdateAlarmList();

    }

    6)删除报警时也需要刷新

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

    https://www.cnblogs.com/bclshuai/p/11380657.html

    百度云盘下载地址:

    链接:https://pan.baidu.com/s/1swkQzCIKI3g3ObcebgpIDg

    提取码:mc8l

    微信公众号获取最新的软件和视频介绍

    QStockView

  • 相关阅读:
    第 33课 C++中的字符串(下)
    第 33课 C++中的字符串(上)
    第32课 初探C++标准库
    第31课 完善的复数类
    第30课 操作符重载
    第29课 类中的函数重载
    C++和C的相互调用
    函数重载遇上函数指针
    函数重载分析
    第2课 算法的效率问题
  • 原文地址:https://www.cnblogs.com/bclshuai/p/9792362.html
Copyright © 2020-2023  润新知