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

