QT中QTableWidget加載大量數(shù)據(jù)不卡頓的解決
最近在模仿網(wǎng)易云音樂的UI,積累自己的代碼能力,在使用QTabbleWidget的時候發(fā)現(xiàn)加載大量數(shù)據(jù)會導(dǎo)致卡頓,這個不能忍。
原因
設(shè)置了自適應(yīng)寬度
// item 水平表頭自適應(yīng)大小 tab->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // item 垂直表頭自適應(yīng)大小 ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); //試著設(shè)置為: QHeaderView::Fixed 看看是否還會卡頓
加載的數(shù)據(jù)太大
解決方案
- QTableView 配合 Model (推薦)
- 我們知道 QTableWidget 每次顯示的數(shù)據(jù)有限(屏幕只有這么大),我們利用這一點來實現(xiàn)動態(tài)加載item,解決卡頓的問題
- 使用事件過濾器,或者 重寫鼠標(biāo)事件,
//需要重寫的虛函數(shù) virtual void wheelEvent(QWheelEvent* event) //事件過濾器 virtual bool eventFilter(QObject* obj, QEvent* event)
舉例說明
1.我們首先先加載一定量的數(shù)據(jù),這樣就不會卡了。
2.為了防止越界,每次循環(huán)我們都應(yīng)該判斷一下
3.用一個 curtableindex 來記錄當(dāng)前數(shù)據(jù)的位置,方便之后加載剩余的數(shù)據(jù)
void SongMenu::loadData() { int len = taglsit.length(); for (int i = 0; i != 20; ++i) { if (i >= len)return; ui->tab_SongTable->insertRow(i); //添加窗口小部件 ui->tab_SongTable->setCellWidget(i, 0, base->setItemWidget(1)); QTableWidgetItem* item1 = new QTableWidgetItem(taglsit.at(i).Title); QTableWidgetItem* item2 = new QTableWidgetItem(taglsit.at(i).Artist); QTableWidgetItem* item3 = new QTableWidgetItem(taglsit.at(i).Ablue); QTableWidgetItem* item4 = new QTableWidgetItem(taglsit.at(i).Duration); ui->tab_SongTable->setItem(i, 1, item1); ui->tab_SongTable->setItem(i, 2, item2); ui->tab_SongTable->setItem(i, 3, item3); ui->tab_SongTable->setItem(i, 4, item4); } curtableindex = 20; //下面例子是加載大量數(shù)據(jù)會卡頓,原因:一次性把所有的數(shù)據(jù)都添加了且設(shè)置了自適應(yīng)寬度 /*foreach(const Temptag & rhs, taglsit) { ui->tab_SongTable->insertRow(index); ui->tab_SongTable->setCellWidget(index, 0, base->setItemWidget(1)); QTableWidgetItem* item1 = new QTableWidgetItem(rhs.Artist); QTableWidgetItem* item2 = new QTableWidgetItem(rhs.Title); QTableWidgetItem* item3 = new QTableWidgetItem(rhs.Ablue); QTableWidgetItem* item4 = new QTableWidgetItem(rhs.Duration); ui->tab_SongTable->setItem(index, 1, item1); ui->tab_SongTable->setItem(index, 2, item2); ui->tab_SongTable->setItem(index, 3, item3); ui->tab_SongTable->setItem(index, 4, item4); }*/ }
這里并沒有加載全部的數(shù)據(jù)。
重新鼠標(biāo)事件
函數(shù)原型:
virtual void wheelEvent(QWheelEvent* event)
wheelEvent() 實現(xiàn)方法
void Base::wheelEvent(QWheelEvent* event) { //滑動一次 y() == 120 //y() > 0 鼠標(biāo)滾輪向前滑動, y() < 0 鼠標(biāo)滾輪向自己滑動 if (event->angleDelta().y() < 0) { emit loadNextPage(); } }
事件過濾器
函數(shù)原型:
virtual bool eventFilter(QObject* obj, QEvent* event)
eventFilter() 實現(xiàn)方法
bool Base::eventFilter(QObject* obj, QEvent* event) { if (obj == tab) { if (event->type() == QEvent::Wheel) { QWheelEvent* wheel = static_cast<QWheelEvent*>(event); //y() < 0 鼠標(biāo)滾輪向自己滑動 if (wheel->angleDelta().y() < 0) { //發(fā)射信號,然后處理數(shù)據(jù) emit loadNextPage(); } } } return QTableWidget::eventFilter(obj,event); } //然后在 構(gòu)造函數(shù)中安裝事件過濾器 ui->tab_SongTable->installEventFilter(this);
實現(xiàn)滑動加載
前面已經(jīng)實現(xiàn)了事件過濾器,和重寫鼠標(biāo)事件,接下來就是加載數(shù)據(jù)了,方法很簡單,只要連接信號,然后加載數(shù)據(jù)就行了
//加載剩余的數(shù)據(jù) connect(base, &Base::loadNextPage, this, [&]() { //每次滾動到底部都加載5條數(shù)據(jù),和前面一樣,檢查邊界,以防越界 for (int i = 0; i != 5; i++) { if (curtableindex >= taglsit.length()) { return; } else { //拿到ui->tab_SongTable尾部的索引,之后往尾部添加數(shù)據(jù) int currow = ui->tab_SongTable->rowCount(); ui->tab_SongTable->insertRow(currow); ui->tab_SongTable->setCellWidget(currow, 0, base->setItemWidget(1)); QTableWidgetItem* item1 = new QTableWidgetItem(taglsit.at(currow).Title); QTableWidgetItem* item2 = new QTableWidgetItem(taglsit.at(currow).Artist); QTableWidgetItem* item3 = new QTableWidgetItem(taglsit.at(currow).Ablue); QTableWidgetItem* item4 = new QTableWidgetItem(taglsit.at(currow).Duration); ui->tab_SongTable->setItem(currow, 1, item1); ui->tab_SongTable->setItem(currow, 2, item2); ui->tab_SongTable->setItem(currow, 3, item3); ui->tab_SongTable->setItem(currow, 4, item4); } //累加索引,防止越界 ++curtableindex ; } });
總結(jié):
到此這篇關(guān)于QT中QTableWidget加載大量數(shù)據(jù)不卡頓的解決的文章就介紹到這了,更多相關(guān)QT中QTableWidget加載卡頓內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vsCode配置import@路徑提示的實現(xiàn)步驟
在導(dǎo)入文件設(shè)置路徑的時候方便了很多,本文主要介紹了vsCode配置import@路徑提示的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2023-08-08