python qt pyqt pyside model-view

python - canFetchMore() y fetchMore() no funcionan como se esperaba



qt pyqt (0)

Tengo problemas para implementar el modelo de árbol Qt con carga canFetchMore() usando canFetchMore() y fetchMore() . Tengo este código:

from PySide.QtCore import Qt, QAbstractItemModel, QModelIndex from PySide.QtWidgets import QTreeView, QApplication BATCH_SIZE = 100 class ObjectItem(object): def __init__(self, parent, name, data, row): self.parent = parent self.name = name self.data = data self.row = row self.hasChildren = False self.canFetchMore = False # ints have no children if isinstance(data, int): return self.childCount = 0 self.childItems = [] if len(data) > 0: self.canFetchMore = True self.hasChildren = True self.childCount = len(self.childItems) if self.childCount > 0: self.hasChildren = True def fetchMore(self): loadedCount = len(self.childItems) totalCount = len(self.data) remainder = totalCount - loadedCount fetchCount = min(BATCH_SIZE, remainder) for _ in range(fetchCount): name = "[{}]".format(loadedCount) value = self.data[loadedCount] self.childItems.append(ObjectItem(self, name, value, loadedCount)) loadedCount += 1 self.canFetchMore = loadedCount < totalCount return fetchCount class MyTreeModel(QAbstractItemModel): def __init__(self, data, parent=None): super(MyTreeModel, self).__init__(parent) self.rootItem = ObjectItem(None, "root", data, 0) self.headerLabels = ["Name", "Type", "Value"] def hasChildren(self, parent=QModelIndex()): return parent.internalPointer().hasChildren if parent.isValid() else True def rowCount(self, parent=QModelIndex()): return parent.internalPointer().childCount if parent.isValid() else 1 def columnCount(self, parent=QModelIndex()): return 3 def index(self, row, column, parent=QModelIndex()): if not parent.isValid(): return self.createIndex(row, column, self.rootItem) parentItem = parent.internalPointer() return self.createIndex(row, column, parentItem.childItems[row]) def parent(self, index): item = index.internalPointer() if item == self.rootItem: return QModelIndex() parentItem = item.parent return self.createIndex(parentItem.row, 0, parentItem) def data(self, index, role): item = index.internalPointer() if role == Qt.DisplayRole: if index.column() == 0: return item.name elif index.column() == 1: return item.data.__class__.__name__ elif index.column() == 2: return repr(item.data) return None def headerData(self, index, orientation, role): if orientation == Qt.Horizontal and role == Qt.DisplayRole: return self.headerLabels[index] return None def canFetchMore(self, parent=QModelIndex()): if parent.isValid(): return parent.internalPointer().canFetchMore else: return False def fetchMore(self, parent=QModelIndex()): parentItem = parent.internalPointer() firstIndex = parentItem.childCount fetchedCount = parentItem.fetchMore() lastIndex = firstIndex + fetchedCount - 1 self.beginInsertRows(parent, firstIndex, lastIndex) parentItem.childCount = len(parentItem.childItems) self.endInsertRows() # test data data = [list(range(1000)), list(range(1000))] app = QApplication([]) view = QTreeView() model = MyTreeModel(data) view.setModel(model) view.show() app.exec_()

Es probablemente la versión más corta (simplificada, no optimizada, no suficientemente general, etc.) del código que puede replicar el problema. Quiero mostrar un árbol de list s de int s. Tenga en cuenta que en el ejemplo anterior tengo dos list de int s, cada una con 1000 int s. Pero por alguna razón desconocida, solo se muestran las primeras 300 int s cuando el nodo se expande y luego me desplazo hacia la parte inferior. Esperaría que los artículos se agreguen mientras me desplazo hacia abajo. Sin embargo, solo se agregan cuando colapso y vuelvo a expandir el nodo.

En otras palabras, los nodos se agregan solo como una reacción al colapso y la expansión de los nodos principales, no como una reacción a desplazarse hacia abajo.

¿Cuál es el problema? ¿He pasado por alto algo?

ACTUALIZACIÓN: Simplifiqué el código aún más, en comparación con la primera versión.

ACTUALIZAR2: Para compararlo con un modelo sin jerarquía, que funciona como se esperaba (obteniendo más datos a medida que el usuario se desplaza hacia abajo), mira este código:

from PySide.QtCore import Qt, QAbstractItemModel, QModelIndex from PySide.QtGui import QApplication, QTreeView BATCH_SIZE = 100 class LazyModel(QAbstractItemModel): def __init__(self, totalCount, parent=None): super(LazyModel, self).__init__(parent) self.items = [] self.totalCount = totalCount self.loadedCount = 0 def hasChildren(self, parent=QModelIndex()): if not parent.isValid(): return True else: return False def rowCount(self, parent=QModelIndex()): return self.loadedCount def columnCount(self, parent=QModelIndex()): return 2 def index(self, row, column, parent=QModelIndex()): return self.createIndex(row, column, None) def parent(self, index): return QModelIndex() def data(self, index, role): if role == Qt.DisplayRole: if index.column() == 0: return str(index.row()) else: return str(self.items[index.row()]) return None def canFetchMore(self, parent=QModelIndex()): return self.loadedCount < self.totalCount def fetchMore(self, parent=QModelIndex()): remainder = self.totalCount - self.loadedCount fetchCount = min(BATCH_SIZE, remainder) for i in range(fetchCount): self.items.append(len(self.items)) self.beginInsertRows(parent, self.loadedCount, self.loadedCount + fetchCount - 1) self.loadedCount += fetchCount self.endInsertRows() app = QApplication([]) view = QTreeView() model = LazyModel(10000) view.setModel(model) view.show() app.exec_()

¿Significa que tengo algo mal con la jerarquía?