Я сделал несколько разных приложений, используя TreeViews
и AbstractItemModels
, но столкнулся с чем-то, чего не понимаю. Я понял, что представление вызывало функцию data
модели, запрашивающую Size
для элементов, поскольку роль была SizeHintRole (см. документацию Qt). Во всех остальных случаях я не помню, чтобы мне приходилось беспокоиться о возврате size
для функции data
. В приведенном ниже коде я ошибочно ожидал, что data
будет просто искать элементы в списке, и если вы раскомментируете первую строку, представление ничего не отобразит, потому что на самом деле представление запрашивает sizeHint
индексов.
У меня вопрос, какие обстоятельства требуют этого? Мне никогда раньше не приходилось предоставлять sizeHint
, и я не понимаю, когда это требуется, а когда нет.
окно, когда первая строка закомментирована
окно, когда первая строка включена, поэтому игнорируйте запрос sizeHint
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()