QTreeWidget Item懒加载

前言

qt界面加载,数据较多时是比较慢的,treeWidget加载数据,跟tableWidget类似思路,先加载部分。

QTreeWidget常用属性设置

    m_treeWidget->setColumnCount(1); //设置列数
    //m_treeWidget->headerItem()->setHidden(true);//隐藏表头
    m_treeWidget->header()->setDefaultSectionSize(20);//默认行高
    m_treeWidget->setMinimumWidth(200);//设置默认最小列宽
    m_treeWidget->setColumnWidth(0, 100);//设置第0列列宽
    //需加 #include 
    m_treeWidget->setStyle(QStyleFactory::create("windows"));//显示节点虚线 - +
    //m_treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);//设置列宽自动分均
    //m_treeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁止编辑
    m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//以行为单位选择
    m_treeWidget->header()->setStyleSheet(
                "QHeaderView::section{background-color:rgb(216,226,236);}"
                "border:0px solid rgb(254,254,254);");//设置表头背景色
    QStringList headList;
    headList << "表头0" <<"表头1";
    m_treeWidget->setHeaderLabels(headList);//设置表头
    //需加 #include 
    m_treeWidget->header()->
            setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter);//表头默认局右
    m_treeWidget->headerItem()->
            setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);//表头0列居左

QTreeWidget源码

直接分享示例代码

.h文件

#ifndef MyTREEWIDGET_H
#define MyTREEWIDGET_H

#include 

#include 
#include 
#include 

class MyTreeWidget:public QWidget
{
public:
    MyTreeWidget(QWidget* parent= nullptr);
    ~MyTreeWidget();

    void InitTree();
    void LoadTreeData();

    void MakeData();
    QString GetStr();

    QTreeWidgetItem*  SetItemText(QTreeWidgetItem* item, QString str);

protected:
    void showEvent(QShowEvent *event) override;
    void hideEvent(QHideEvent *event) override;
private:
    bool m_bShow;
    int m_itemShowCnt;
    QTreeWidget* m_treeWidget;
    QTreeWidgetItem* m_topItem_1;
    QTreeWidgetItem* m_topItem_2;
    QMap<QString,QStringList> m_map;
};

#endif // MyTREEWIDGET_H

.cpp文件

#include "mytreewidget.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
MyTreeWidget::MyTreeWidget(QWidget* parent)
    :QWidget(parent)
{
    resize(200,500);
    qsrand(time(NULL));
    m_bShow = false;
}

MyTreeWidget::~MyTreeWidget()
{

}

void MyTreeWidget::InitTree()
{
    QVBoxLayout* vbox =new QVBoxLayout;
    vbox->setMargin(0);
    m_treeWidget = new QTreeWidget(this);
    m_treeWidget->setColumnCount(1); //设置列数
    //m_treeWidget->headerItem()->setHidden(true);//隐藏表头
    m_treeWidget->header()->setDefaultSectionSize(20);//默认行高
    m_treeWidget->setMinimumWidth(200);//设置默认最小列宽
    m_treeWidget->setColumnWidth(0, 100);//设置第0列列宽
    //需加 #include 
    m_treeWidget->setStyle(QStyleFactory::create("windows"));//显示节点虚线 - +
    //m_treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch);//设置列宽自动分均
    //m_treeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁止编辑
    m_treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//以行为单位选择
//    m_treeWidget->header()->setStyleSheet(
//                "QHeaderView::section{background-color:rgb(216,226,236);}"
//                "border:0px solid rgb(254,254,254);");//设置表头背景色
    QStringList headList;
    headList << "表头0" <<"表头1";
    m_treeWidget->setHeaderLabels(headList);//设置表头
    //需加 #include 
    m_treeWidget->header()->
            setDefaultAlignment(Qt::AlignRight | Qt::AlignVCenter);//表头默认局右
    m_treeWidget->headerItem()->
            setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter);//表头0列居左
    vbox->addWidget(m_treeWidget);
    setLayout(vbox);

    m_topItem_1 = new  QTreeWidgetItem(m_treeWidget);
    m_topItem_2 = new  QTreeWidgetItem(m_treeWidget);
    m_topItem_1->setText(0,"ProJect");
    m_topItem_2->setText(0,"TestCase");

    m_treeWidget->addTopLevelItem(m_topItem_1);
    m_treeWidget->addTopLevelItem(m_topItem_2);

    m_itemShowCnt = 30;//设置默认item加载数量

    //展开加载
    connect(m_treeWidget,&QTreeWidget::itemExpanded,this,[=](QTreeWidgetItem *item)
    {
        if(item != m_topItem_1 && item != m_topItem_2 && item->childCount() == 1)//初次展开则加载
        {
            QMap<QString,QStringList>::iterator itor =  m_map.find(item->text(0));
            if(itor == m_map.end())
                return;
            QStringList strList = itor.value();
            for (int i=1;i!=strList.length(); i++)//从第0个已经加载
            {
                SetItemText(item, itor.value().at(i));
            }
        };
    });
    //折叠
    connect(m_treeWidget,&QTreeWidget::itemCollapsed,this,[=](QTreeWidgetItem *item)
    {
        qDebug()<<"折叠";
    });
    //绑定滚动条,根据滚动条值改变来加载
    connect(m_treeWidget->verticalScrollBar(),&QScrollBar::valueChanged,[=](int value)
    {
        int currentItemCnt = m_topItem_1->childCount();//已加载topItem数量
        //滚动条移动到底端且未加载完
        if(value == m_treeWidget->verticalScrollBar()->maximum() && currentItemCnt < m_map.size())
        {
            QMap<QString,QStringList>::iterator itor =  m_map.begin();
            for (int i=0; i<currentItemCnt; i++)
            {
                if(itor == m_map.end())
                    break;
                itor++;
            }
            for (int i=0;itor!=m_map.end(); itor++,i++)
            {
                if(i > m_itemShowCnt)
                    break;//每次滚动条滑到底时,再加载一些item数量

                QTreeWidgetItem*  item = SetItemText(m_topItem_1, itor.key());//默认先加载一个
                SetItemText(item, itor.value().at(0));//默认先加载一个
            }
        }
    });


    //线程加载数据
    QThread* thread = new QThread();
    connect(thread, &QThread::started, thread, [=]()mutable{
        qDebug()<<"started!";
        MakeData();
        thread->quit();
    }, Qt::DirectConnection);//这里要加 Qt::DirectConnection 在线程执行
    connect(thread, &QThread::finished, this, [=]()mutable{
        thread->wait();
        thread->deleteLater();
        qDebug()<<"finished!";
        LoadTreeData();
    });
    thread->start();
}

void MyTreeWidget::MakeData()
{
    int topItem = 1000;
    int item = 1000;
    for (int i=0; i<topItem;i++)
    {
        QStringList strList;
        for (int j=0; j<item;j++)
        {
            strList.append(QString::number(j) + GetStr());
        }
        m_map.insert(QString::number(i) + GetStr(),strList);
    }

    qDebug()<<"MakeData:"<<m_map.size();
}

void MyTreeWidget::LoadTreeData()
{
    QMap<QString,QStringList>::iterator itor =  m_map.begin();
    for (int i=0; itor != m_map.end(); itor++,i++) {
        if(i > m_itemShowCnt)
            break;//只加载默认item数量
        QTreeWidgetItem* item = SetItemText(m_topItem_1, itor.key());
        SetItemText(item, itor.value().at(0));
    }
}

void MyTreeWidget::showEvent(QShowEvent *event)
{
    if(!m_bShow)
    {
        InitTree();
        m_bShow = true;
    }
}

void MyTreeWidget::hideEvent(QHideEvent *event)
{

}

QTreeWidgetItem*  MyTreeWidget::SetItemText(QTreeWidgetItem *item, QString str)
{
    QTreeWidgetItem* childItem = new QTreeWidgetItem;
    item->addChild(childItem);
    childItem->setText(0,str);
    return childItem;
}

QString MyTreeWidget::GetStr()
{
   int length = rand()%15+5;
   const char ch[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   int size = sizeof(ch);
   char* str = new char[length + 1];
   int num = 0;
   int i;
   for (i = 0; i < length; ++i)
   {
       num = rand() % (size - 1);
       str[i] = ch[num];
   }
    str[i] = '\0';
   QString res(str);
   //return res;
   return "《"+res+"》";
}

QTreeWidget Item懒加载_第1张图片

你可能感兴趣的:(qt,c++,开发语言,qt)