QT中QTableWidget加載大量數(shù)據(jù)不卡頓的解決
最近在模仿網(wǎng)易云音樂(lè)的UI,積累自己的代碼能力,在使用QTabbleWidget的時(shí)候發(fā)現(xiàn)加載大量數(shù)據(jù)會(huì)導(dǎo)致卡頓,這個(gè)不能忍。
原因
設(shè)置了自適應(yīng)寬度
// item 水平表頭自適應(yīng)大小 tab->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // item 垂直表頭自適應(yīng)大小 ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); //試著設(shè)置為: QHeaderView::Fixed 看看是否還會(huì)卡頓
加載的數(shù)據(jù)太大
解決方案
- QTableView 配合 Model (推薦)
- 我們知道 QTableWidget 每次顯示的數(shù)據(jù)有限(屏幕只有這么大),我們利用這一點(diǎn)來(lái)實(shí)現(xiàn)動(dòng)態(tài)加載item,解決卡頓的問(wèn)題
- 使用事件過(guò)濾器,或者 重寫(xiě)鼠標(biāo)事件,
//需要重寫(xiě)的虛函數(shù) virtual void wheelEvent(QWheelEvent* event) //事件過(guò)濾器 virtual bool eventFilter(QObject* obj, QEvent* event)
舉例說(shuō)明
1.我們首先先加載一定量的數(shù)據(jù),這樣就不會(huì)卡了。
2.為了防止越界,每次循環(huán)我們都應(yīng)該判斷一下
3.用一個(gè) curtableindex 來(lái)記錄當(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ù)會(huì)卡頓,原因:一次性把所有的數(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); }*/ }
這里并沒(méi)有加載全部的數(shù)據(jù)。
重新鼠標(biāo)事件
函數(shù)原型:
virtual void wheelEvent(QWheelEvent* event)
wheelEvent() 實(shí)現(xiàn)方法
void Base::wheelEvent(QWheelEvent* event) { //滑動(dòng)一次 y() == 120 //y() > 0 鼠標(biāo)滾輪向前滑動(dòng), y() < 0 鼠標(biāo)滾輪向自己滑動(dòng) if (event->angleDelta().y() < 0) { emit loadNextPage(); } }
事件過(guò)濾器
函數(shù)原型:
virtual bool eventFilter(QObject* obj, QEvent* event)
eventFilter() 實(shí)現(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)滾輪向自己滑動(dòng) if (wheel->angleDelta().y() < 0) { //發(fā)射信號(hào),然后處理數(shù)據(jù) emit loadNextPage(); } } } return QTableWidget::eventFilter(obj,event); } //然后在 構(gòu)造函數(shù)中安裝事件過(guò)濾器 ui->tab_SongTable->installEventFilter(this);
實(shí)現(xiàn)滑動(dòng)加載
前面已經(jīng)實(shí)現(xiàn)了事件過(guò)濾器,和重寫(xiě)鼠標(biāo)事件,接下來(lái)就是加載數(shù)據(jù)了,方法很簡(jiǎn)單,只要連接信號(hào),然后加載數(shù)據(jù)就行了
//加載剩余的數(shù)據(jù) connect(base, &Base::loadNextPage, this, [&]() { //每次滾動(dòng)到底部都加載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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?Qt實(shí)現(xiàn)動(dòng)態(tài)增加垂直滾動(dòng)條
本博文源于筆者正在工作的一個(gè)小內(nèi)容,內(nèi)容涉及到為qt動(dòng)態(tài)增加垂直滾動(dòng)條,文章分為三個(gè)部分,問(wèn)題起源,問(wèn)題解決方案,問(wèn)題解決成功效果,思路清晰,文章干貨滿滿,復(fù)制源碼即可使用,需要的朋友可以參考下2023-08-08C語(yǔ)言實(shí)現(xiàn)靜態(tài)版通訊錄的代碼分享
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的靜態(tài)版通訊錄,主要運(yùn)用了結(jié)構(gòu)體,一維數(shù)組,函數(shù),分支與循環(huán)語(yǔ)句等等知識(shí),需要的可以參考一下2023-01-01vsCode配置import@路徑提示的實(shí)現(xiàn)步驟
在導(dǎo)入文件設(shè)置路徑的時(shí)候方便了很多,本文主要介紹了vsCode配置import@路徑提示的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08C語(yǔ)言學(xué)習(xí)之關(guān)鍵字的示例詳解
關(guān)鍵字,這名字一聽(tīng),就很關(guān)鍵。而有些關(guān)鍵字,你可能不是很了解,更別談使用。所以,這篇文章將帶你見(jiàn)識(shí)常見(jiàn)的關(guān)鍵字,一起領(lǐng)略它們的風(fēng)采吧2022-10-10C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷效果
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)萬(wàn)年歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11