- 目的:加快進入界面時候加快圖片加載的速度,每一行的圖片根據數據的變化而顯示不同的圖片樣式,數據變化則圖片根據數據而變化。(注意是根據某一行或者某一列的數據改變)。只是一種實現方法,不講原理。
- 方法說明
(1) 一般來說如果數據量不大使用視圖自帶的函數setIndexWidget(const QModelIndex & index, QWidget * widget)可以添加一些自定義控件之類的。但是如果一個界面擁有大量的圖片數據的時候,再使用該方法效率及其低下,最直觀的一點就是第一次進入該界面的時候會感覺到明顯的延遲。(之前測試20行40張圖片,debug模式下第一次加載界面將近2s,用代理的方法200ms都不到起碼視覺上幾乎感覺不到延遲,release模式下更快,這里還有數據庫讀取也算上了,數據庫當時只讀取了一次大概50ms左右,速度上來講10倍的差距)。
(2) 該方法是在代理提供的默認方法上面添加的改進方案。正常來講一般都是直接代理一整行或者一整列。(網上方案很多這里不予舉例)
(3) 該方案主要利用的是視圖/模型中自帶的信號dataChanged觸發對應單元格的重繪功能。
(4) 該方案只提供核心代碼和思路。
- 思路/及代碼說明
(1) 代理類
代理頭文件
圖 1 代理聲明
代理頭文件實現:
繼承QStyledItemDelegate並重寫paint,editorEvent函數。
代理實現
圖 2 代理實現
① 代碼說明
② 改代碼實現的代理效果是一個button按鈕。
③ StationsStatus 在paint中的stationStatus類是一個單例的概念,他記錄了表格中對應行的當前狀態。這個信息狀態可以直接存儲在QStandardItem的data中,但是我這邊有多個界面都用到了這個信息所以直接抽象出來了。
④ 注釋掉的代碼是關於按鈕的按下,懸浮(hover)等效果,我這邊不需要就屏蔽掉了,如果想要對應效果開啟這部分代碼,並在下方寫上對應的qss或者直接在判斷分支里面重新手動繪制想要的效果都可以。這部分網上也有很多不做多余解釋。
⑤ editorEvent中在鼠標釋放的時候觸發了對應的按鈕信號,其實並不是按鈕發出的信號,而是鼠標在單元格內規定的范圍之按下了按鈕所以觸發了對應的效果。相當於模擬QPushButton的click信號。如果一個單元格之內想放入多個按鈕的話,並實現對應的信號可以參考如下方法。
⑥ 多按鈕參考網址: https://www.codeleading.com/article/55535964738/
⑦ 這里已經是核心代碼了,剩下的就是當狀態改變的時候如果觸發對應單元格的重繪事件,如開頭所說,當對應的dataChange(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ())被觸發的時候,就會觸發對應的重繪功能。
[注]該代理實現的是類似於開關的功能,狀態改變時會有不同的圖片顯示,如果只是單純的向放入圖片不要其他功能的話可以在這里放入一個QLabel/Qwidget...editorEvente中不要觸發相應信號即可,但是代碼會有些許不同,網上找兩個不同代理的實例看一下就明白了.
(2) 加載代理類
① 實現代碼
圖 3 加載代理類
② 如果代理中放入的是QPushButton並想實現對應的hover效果,則還要開啟對應表格的鼠標追蹤事件,這個對我們的功能來說可有可無。想要這個效果的話可以開啟。
ui->treeStation->setMouseTracking(true);
樹或者表都一樣,按照如上方法可開啟對應鼠標追蹤事件。
③ SlotConnectStation 點擊按鈕觸發事件實現
圖 4 按鈕點擊事件觸發
代碼說明:通過單例獲取當前按鈕狀態,單擊按鈕之后如果不需要執行一些事務可以直接把slotStationStatusChange 的代碼放入這里,直接修改對應圖片就行。這里的socket可以了理解為我自己的事務類,他會處理對應點擊事件所要執行的事務。如上沒有事務直接改圖片就成。
④ slotStationStatusChange 根據狀態修改對應圖片方法
圖 5 根據狀態切換圖片
slotStationStatusChange 這個函數在我的執行邏輯中只有狀態被改變的才會觸發,也就是說這個被觸發了當前一定切換了狀態。
核心代碼就是:statusItem->setData(status,Qt::UserRole);只要data中有對應角色的內容被修改了,dataChange就會被觸發,進而觸發對應單元格的paint函數重新繪制對應圖片。
⑤ slotSendConnectCmdError 修改狀態失敗(我們這里並不需要對應的功能,但是代碼還是貼上)
圖 6 錯誤提示功能
該函數在我這里只有狀態切換失敗之后會被觸發。這里的功能可以理解為QMessageBox,一個提示效果。
核心代碼就是代理類的實現,圖片實時切換功能的實現就是通過狀態信息和代理重繪配合,說白了就是手動控制器這個圖片是否切換。