Я сделал несколько разных приложений, используя TreeViews
и AbstractItemModels
, но наткнулся на то, чего я не понимаю. Я понял, что представление вызывает функцию data
модели, запрашивающую Size
для элементов, поскольку роль была SizeHintRole (, см. Документацию Qt ). Во всех других случаях я никогда не вспоминаю о необходимости беспокоиться о возвращении size
для функции data
. В приведенном ниже коде я ошибочно ожидал, что data
будет просто искать элементы в списке, и если вы раскомментируете первую строку, представление ничего не отображает, потому что на самом деле представление запрашивает sizeHint
индексов .
Мой вопрос: какие обстоятельства требуют этого? Мне никогда не приходилось предоставлять sizeHint
раньше, и я не понимаю, когда это требуется, а когда нет.
окно, когда закомментирована первая строка
![enter image description here](https://i.stack.imgur.com/4w5vE.png)
окно, когда включена первая строка, поэтому игнорируйте запрос sizeHint
![enter image description here](https://i.stack.imgur.com/LzMwU.png)
import sys
from PyQt5 import QtCore, QtWidgets
class TreeList:
def __init__(self):
self._items = list()
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, root, parent=None):
super().__init__(parent)
self.root = root
def index(self, row: int, column: int, parent: QtCore.QModelIndex = ...) -> QtCore.QModelIndex:
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
if not parent.isValid():
pointer = self.root # type: TreeList
child = pointer._items[row]
else:
child = None
return self.createIndex(row, column, child)
def addItem(self, layer):
row = len(self.root._items)
self.beginInsertRows(QtCore.QModelIndex(), row, row)
self.root._items.append(layer)
self.endInsertRows()
def parent(self, child: QtCore.QModelIndex) -> QtCore.QModelIndex:
return QtCore.QModelIndex()
def rowCount(self, parent: QtCore.QModelIndex = ...) -> int:
if parent.isValid():
return 0
else:
return len(self.root._items)
def columnCount(self, parent: QtCore.QModelIndex = ...) -> int:
return 1
def hasChildren(self, parent: QtCore.QModelIndex = ...) -> bool:
return False if parent.isValid() else True
def data(self, index: QtCore.QModelIndex, role: int = ...):
# return self.root._items[index.row()]
if role == QtCore.Qt.SizeHintRole:
print(index.isValid(), index.row(), index.column())
return QtCore.QSize(100, 20)
else:
return self.root._items[index.row()]
def flags(self, index: QtCore.QModelIndex):
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
class StackTreeView(QtWidgets.QTreeView):
def __init__(self, data=None, parent=None):
super().__init__(parent)
self.setModel(TreeModel(data))
def addItem(self, layer):
self.model().addItem(layer)
def test():
app = QtWidgets.QApplication(sys.argv)
data = TreeList()
data._items = ['one', 'two']
sys.excepthook = sys.__excepthook__
tree_view = StackTreeView(data)
tree_view.show()
tree_view.addItem('three')
tree_view.addItem('four')
sys.exit(app.exec_())
if __name__ == '__main__':
test()