Skip to content

Instantly share code, notes, and snippets.

@internetimagery
Created July 21, 2022 11:16
Show Gist options
  • Save internetimagery/6a9768438826ddf9e69778dc574dbb75 to your computer and use it in GitHub Desktop.
Save internetimagery/6a9768438826ddf9e69778dc574dbb75 to your computer and use it in GitHub Desktop.
Simple lazy model
from PyQt5 import QtWidgets, QtCore
import gevent
import random
import weakref
def getData(key):
data = "{}_{}_{}".format(key[0], key[1], random.choice("abcdefg"))
gevent.sleep(random.random() * 5 + 2)
return data
class Model(QtCore.QAbstractItemModel):
def __init__(self, parent=None):
super(Model, self).__init__(parent)
self._data = {}
self._procs = weakref.WeakSet()
def columnCount(self, index, parent=None):
return 3
def rowCount(self, index, parent=None):
if not index.isValid():
return 2
return 0
def parent(self, index):
return QtCore.QModelIndex()
def index(self, row, col, parent=None):
return self.createIndex(row, col)
def reset(self):
self.beginResetModel()
while self._procs:
proc = self._procs.pop()
proc.kill()
self._data.clear()
self.endResetModel()
def data(self, index, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.DisplayRole:
return None
key = index.row(), index.column()
try:
return self._data[key]
except KeyError:
proc = gevent.spawn(getData, key)
proc.link(lambda p: self._dataUpdate(key, p.get()))
self._procs.add(proc)
self._data[key] = None
return None
def _dataUpdate(self, key, value):
self._data[key] = value
index = self.index(*key)
self.dataChanged.emit(index, index)
class Main(QtWidgets.QMainWindow):
def __init__(self):
super(Main, self).__init__(None)
layout = QtWidgets.QVBoxLayout()
self._tree = QtWidgets.QTreeView()
self._tree.setModel(Model())
layout.addWidget(self._tree)
self._reset = QtWidgets.QPushButton("Reset")
self._reset.clicked.connect(self._handleReset)
layout.addWidget(self._reset)
container = QtWidgets.QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
def _handleReset(self):
self._tree.model().reset()
if __name__ == "__main__":
app = QtWidgets.QApplication([])
win = Main()
win.show()
loop = QtCore.QTimer()
loop.setInterval(10)
loop.timeout.connect(lambda: gevent.sleep(0.01))
loop.start()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment