我有一個子類QAbstractListModel是 QML 的模型ListView(使用 PySide6)。串列的每一行都有一個復選框,當用戶選中/取消選中一個框時,它會使用我的覆寫更新 listmodel 的該行中的布林值setData(),這可以按預期作業。我也有Buttons 應該選擇/清除串列中的所有復選框。
Button我的模型子類提供了以下方法來選擇所有,當用戶點擊或應用程式中發生其他事情時可以呼叫該方法:
def select_all(self):
for i in range(self.rowCount()):
row = self._rows[i]
row['selected'] = True
# Emitting this for each row works...
self.dataChanged.emit(self.index(i), self.index(i), [])
# ... whereas emitting just one signal for ALL rows does NOT work
# self.dataChanged.emit(self.index(0), self.index(self.rowCount()), [])
正如您從評論中看到的那樣,我需要dataChanged為每一行發出,以便ListView更新中的復選框。發出一次信號并使用topLeftandbottomRight引數不會更新復選框中的狀態ListView(但模型資料已正確更新)。
根據檔案,dataChanged由QAbstractItemModel(和繼承QAbstractListModel)提供的信號有這個警告:
如果專案屬于同一父項,則受影響的專案是 topLeft 和 bottomRight 之間的專案。如果專案沒有相同的父項,則行為未定義。
我似乎遇到了這樣一種情況,即我的模型中的行沒有相同的父級,因此“行為未定義”。我想這是有道理的,因為我從來沒有做任何事情來為我的任何行建立父/子關系。我還看到了這個答案,這意味著當topLeft和bottomRight索引相同時,Qt 的行為會有所不同。所以,我想更好地理解這一點,我有幾個問題:
- 我是否正確,這個父概念是它在為每一行發出時確實有效并且不適用于所有行的原因?
- Is the concept of a parent/child relationship only meaningful for tree-like models that would extend
QAbstractItemModelinstead ofQAbstractListModel? Does it make any kind of sense for a list? - If it does make sense for a list, then what would be the "parent" and what would be the "child?" How would I configure a subclass of
QAbstractListModelsuch thatdataChangedcan be emitted once to update multiple rows?
Thanks!
uj5u.com熱心網友回復:
雖然 Qt 專案視圖的基本實作只是在topLeft和bottomRight索引不匹配時不加選擇地更新視圖(因此您可以只提供兩個“隨機”,但仍然是同級索引),索引不僅必須共享一個共同的父級(這對于一維和二維模型始終是無效索引),但也都是有效的。
使用此行,第二個索引無效:
self.dataChanged.emit(self.index(0), self.index(self.rowCount()), [])
這是因為索引總是從 0 開始的,而最后一行的索引實際上是rowCount - 1. 雖然理論上它們是兄弟姐妹,但由于它們共享相同的父級(根索引的父級無效,因為它是無效索引的父級),但它們并非都有效。
所以,正確的語法是:
self.dataChanged.emit(self.index(0), self.index(self.rowCount() - 1), [])
^^^^
請注意,該roles引數是可選的,并且已經默認為一個空串列(C 中的 QVector),因此除非您確實想要指定更改后的角色,否則您不需要提供它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/443303.html
標籤:qt qml qabstractitemmodel pyside6 qabstractlistmodel
下一篇:QTextEdit占位符顏色
