title: CPU overload when updating QListView from QAbstractListModel
body: <p>I'm building a little pyqt5 app that display a list of 512 values in a QListView. The list is updated through separate thread, with QThread.
  It's working nice, except the fact that it is using 65/95 % of the CPU of the (old) Core 2 Duo 2,53 Ghz I'm developing on.</p>
  
  <p>I simplify the code to remove dependancies, because the update is done from a network protocol. Updates are done 40 times per second (each 25 ms). </p>
  
  <p>The simplified script below is refreshing the list 10 times per second and the CPU is still at 65 % when list is updated.</p>
  
  <p>Is there anything to do for avoiding the overload?
  Is there some best practices to follow for updating a View?</p>
  
  <p>(the global is not in my last code, it's here to have a simple example)</p>
  
  <pre><code>from random import randrange
  from time import sleep
  from sys import argv, exit
  from PyQt5.QtCore import QThread, QAbstractListModel, Qt, QVariant, pyqtSignal
  from PyQt5.QtWidgets import QListView, QApplication, QGroupBox, QVBoxLayout, QPushButton
  
  universe_1 = [0 for i in range(512)]
  
  class SpecialProcess(QThread):
      universeChanged = pyqtSignal()
      def __init__(self):
          super(SpecialProcess, self).__init__()
          self.start()
  
      def run(self):
          global universe_1
          universe_1 = ([randrange(0, 101, 2) for i in range(512)])
          self.universeChanged.emit()
          sleep(0.1)
          self.run()
  
  
  class Universe(QAbstractListModel):
      def __init__(self, parent=None):
          super(Universe, self).__init__(parent)
  
      def rowCount(self, index):
          return len(universe_1)
  
      def data(self, index, role=Qt.DisplayRole):
          index = index.row()
          if role == Qt.DisplayRole:
              try:
                  return universe_1[index]
              except IndexError:
                  return QVariant()
          return QVariant()
  
  
  class Viewer(QGroupBox):
      def __init__(self):
          super(Viewer, self).__init__()
          list_view = QListView()
          self.list_view = list_view
          # create a vertical layout
          vbox = QVBoxLayout()
          universe = Universe()
          vbox.addWidget(list_view)
          # Model and View setup
          self.model = Universe(self)
          self.list_view.setModel(self.model)
          # meke a process running in parallel 
          my_process = SpecialProcess()
          my_process.universeChanged.connect(self.model.layoutChanged.emit)
          # set the layout on the groupbox
          vbox.addStretch(1)
          self.setLayout(vbox)
  
  
  if __name__ == "__main__":
    app = QApplication(argv)
    group_widget = Viewer()
    group_widget.show()
    exit(app.exec_())
  </code></pre>