Guest User

MWE 1.1

a guest
Jan 27th, 2021
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.66 KB | None | 0 0
  1. import sys
  2. from PySide6 import (
  3.     QtCore,
  4.     QtWidgets
  5. )
  6.  
  7.  
  8. class Node(QtCore.QObject):
  9.     def __init__(self, val: str, model, parent=None):
  10.         super().__init__(parent)
  11.         self.value = val
  12.         self._model = model
  13.  
  14.     def child_count(self) -> int:
  15.         return len(self.children())
  16.  
  17.     def get_child(self, row: int) -> "Node":
  18.         if row < 0 or row >= self.child_count():
  19.             return None
  20.         else:
  21.             return self.children()[row]
  22.  
  23.     def get_model_index(self) -> QtCore.QModelIndex:
  24.         return self._model.index(self.get_row_in_parent(), 0, self.parent().get_model_index())
  25.  
  26.     def get_row_in_parent(self) -> int:
  27.         p = self.parent()
  28.         if p is not None:
  29.             return p.children().index(self)
  30.  
  31.         return -1
  32.  
  33.  
  34. class RootNode(Node):
  35.     def get_row_in_parent(self) -> int:
  36.         return -1
  37.  
  38.     def get_model_index(self) -> QtCore.QModelIndex:
  39.         return QtCore.QModelIndex()
  40.  
  41.  
  42. class Model(QtCore.QAbstractItemModel):
  43.     def __init__(self, parent=None):
  44.         super().__init__(parent)
  45.  
  46.         self.root_item = None
  47.  
  48.         # simulate the changing data
  49.         self._data = [
  50.             (1, 'child 1 of 1'),
  51.             (1, 'child 2 of 1'),
  52.             (1, 'child 3 of 1'),
  53.         ]
  54.  
  55.         self._initialize_static_part()
  56.  
  57.         self.update()
  58.  
  59.     def _initialize_static_part(self):
  60.         """This is the part of my model which never changes at runtime
  61.        """
  62.         self.root_item = RootNode('root', self, self)
  63.  
  64.         nodes_to_add = []
  65.  
  66.         for i in range(0, 5):
  67.             new_node = Node(str(i), self)
  68.             nodes_to_add.append(new_node)
  69.  
  70.         for node in nodes_to_add:
  71.             self.add_node(node, self.root_item)
  72.  
  73.     def update(self):
  74.         """This is the part which needs update during runtime
  75.        """
  76.  
  77.         rows_to_add = []
  78.         rows_to_delete = []
  79.  
  80.         for c in self.root_item.children():
  81.             for d in c.children():
  82.                 rows_to_delete.append(d)
  83.  
  84.         for (parent_identifier, name) in self._data:
  85.             node = Node(name, self)
  86.             #  actually, the future parent is a different function, but for the MWE this suffices
  87.             future_parent = self.root_item.get_child(parent_identifier)
  88.             rows_to_add.append((future_parent, node))
  89.  
  90.         for node in rows_to_delete:
  91.             self.remove_node(node)
  92.  
  93.         for (parent, node) in rows_to_add:
  94.             self.add_node(node, parent)
  95.  
  96.     def add_node(self, node: Node, parent: Node):
  97.         self.beginInsertRows(parent.get_model_index(),
  98.                              parent.child_count(),
  99.                              parent.child_count())
  100.         node.setParent(parent)
  101.         self.endInsertRows()
  102.  
  103.     def remove_node(self, node):
  104.         parent_node = node.parent()
  105.         row = parent_node.get_model_index().row()
  106.         self.beginRemoveRows(parent_node.get_model_index(
  107.         ), row, row)
  108.         print(parent_node.get_model_index().isValid())
  109.  
  110.         node.setParent(None)
  111.  
  112.         print(node)
  113.         print(parent_node.children())
  114.  
  115.         self.endRemoveRows()
  116.         # reimplement virtual method
  117.  
  118.     def columnCount(self, parent: QtCore.QModelIndex = QtCore.QModelIndex()) -> int:
  119.         return 1
  120.  
  121.     # reimplement virtual method
  122.     def rowCount(self, parent: QtCore.QModelIndex = QtCore.QModelIndex()) -> int:
  123.         if not parent.isValid():
  124.             parent_item = self.root_item
  125.         else:
  126.             parent_item = parent.internalPointer()
  127.  
  128.         return parent_item.child_count()
  129.  
  130.     # reimplement virtual method
  131.     def index(self, row: int, column: int, parent: QtCore.QModelIndex = QtCore.QModelIndex()) -> QtCore.QModelIndex:
  132.         if not self.hasIndex(row, column, parent):
  133.             return QtCore.QModelIndex()
  134.  
  135.         if not parent.isValid():
  136.             parent_item = self.root_item
  137.         else:
  138.             parent_item = parent.internalPointer()
  139.  
  140.         child_item: Node = parent_item.get_child(row)
  141.         if child_item is not None:
  142.             return self.createIndex(row, column, child_item)
  143.  
  144.         return QtCore.QModelIndex()
  145.  
  146.     # reimplement virtual method
  147.     def parent(self, index: QtCore.QModelIndex) -> QtCore.QModelIndex:
  148.         if not index.isValid():
  149.             return QtCore.QModelIndex()
  150.  
  151.         child_item: Node = index.internalPointer()
  152.         parent_item = child_item.parent()
  153.  
  154.         if parent_item is not None:
  155.             return parent_item.get_model_index()
  156.  
  157.         return QtCore.QModelIndex()
  158.  
  159.     # reimplement virtual method
  160.     def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.DisplayRole) -> object:
  161.         if not index.isValid():
  162.             return None
  163.  
  164.         if role == QtCore.Qt.DisplayRole:
  165.             item: Node = index.internalPointer()
  166.             if item is not None:
  167.                 return item.value
  168.             return 'whats this?'
  169.  
  170.         return None
  171.  
  172.  
  173. class MyWindow(QtWidgets.QMainWindow):
  174.     defaultsize = QtCore.QSize(780, 560)
  175.  
  176.     def __init__(self, app, parent=None):
  177.         super().__init__(parent)
  178.         self.app = app
  179.         self.resize(self.defaultsize)
  180.         main_layout = QtWidgets.QSplitter(QtCore.Qt.Vertical)
  181.         self.panel = Panel(main_layout)
  182.         self.setCentralWidget(main_layout)
  183.  
  184.         self.model = Model(self)
  185.  
  186.         proxy_model1 = QtCore.QSortFilterProxyModel(self)
  187.         proxy_model1.setSourceModel(self.model)
  188.  
  189.         proxy_model2 = QtCore.QIdentityProxyModel(self)
  190.         proxy_model2.setSourceModel(self.model)
  191.  
  192.         view1 = QtWidgets.QTreeView(self.panel)
  193.         view1.setAlternatingRowColors(True)
  194.         view1.setModel(proxy_model1)
  195.         view1.expandAll()
  196.  
  197.         view2 = QtWidgets.QTreeView(self.panel)
  198.         view2.setAlternatingRowColors(True)
  199.         view2.setModel(proxy_model2)
  200.         view2.expandAll()
  201.  
  202.         self.panel.addWidget(view1)
  203.         self.panel.addWidget(view2)
  204.  
  205.         # we simulate a change, which would usually be triggered manually
  206.         def manual_change_1():
  207.             self.model._data = [
  208.                 (1, 'child 2 of 1'),
  209.                 (1, 'child 3 of 1'),
  210.             ]
  211.             self.model.update()
  212.  
  213.         QtCore.QTimer.singleShot(2000, manual_change_1)
  214.  
  215.  
  216. class App(QtWidgets.QApplication):
  217.     def __init__(self):
  218.         super().__init__()
  219.         self.window = MyWindow(self)
  220.  
  221.     def run(self):
  222.         self.window.show()
  223.         result = self.exec_()
  224.         self.exit()
  225.  
  226.  
  227. class Panel(QtWidgets.QSplitter):
  228.     pass
  229.  
  230.  
  231. if __name__ == '__main__':
  232.     app = App()
  233.     app.startTimer(1000)
  234.  
  235.     sys.exit(app.run())
  236.  
Advertisement
Add Comment
Please, Sign In to add comment