title: canFetchMore() and fetchMore() are not working as expected
body: <p>I have problems implementing Qt tree model with lazy loading using <code>canFetchMore()</code> and <code>fetchMore()</code>. I have this code:</p>
  
  <pre><code>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) &gt; 0:
              self.canFetchMore = True
              self.hasChildren = True
  
          self.childCount = len(self.childItems)
          if self.childCount &gt; 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 &lt; 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_()
  </code></pre>
  
  <p>It is probably the shortest version (simplified, unoptimized, not general enough etc.) of the code which can replicate the problem. I want to display a tree of <code>list</code>s of <code>int</code>s. Note that in the example above I have two <code>list</code>s of <code>int</code>s, each containing 1000 <code>int</code>s. But for some unknown reason, only he first 300 <code>int</code>s are displayed when the node is expanded and after I scroll to the very bottom. I would expect that the items should be added as I am scrolling down. However they are only added when I collapse and expand again the node.</p>
  
  <p>In other words, the nodes are being added only as a reaction to collapsing and expanding of the parent nodes, not as a reaction to scrolling to the bottom.</p>
  
  <p>What is the problem? Have I overlooked anything?</p>
  
  <p>UPDATE: I simplified the code even more, compared to the first version.</p>
  
  <p>UPDATE2: To compare it with a model without hierarchy, which works as expected (fetching more data as user scrolls down), look at this code:</p>
  
  <pre><code>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 &lt; 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_()
  </code></pre>
  
  <p>Does it mean I got something wrong with hierarchy?</p>