0

I want to create a TreeTable with a given data from a list of lists. At the moment I only managed to create a normal table with the help of a QTableView and a QAbstractTableModel. Now I want to convert this into a tree.

The tree should look something like this:

Event        Time       Parent    Deepness
A           00:00:01    True        0
--> B       00:00:05    False       1
----> C     00:00:07    False       2
-------> D  00:00:08    False       3
----> E     00:00:13    False       2
--> F       00:00:17    False       1
G           00:00:21    True        0
--> H       00:00:21    False       1   
--> I       00:00:21    False       1,
J           00:00:21    True        0

That means that A is a parent of B and B is a parent of C and so on... The last value of every list will show the deepness of every row. So 0 marks a parent, 1 a child, 2 a child-child ... If there is a better way of presenting the given data, I could possibly customize that.

Here is my approach to create a standard QTableView:

from PyQt5 import QtWidgets, QtGui, QtCore
import pandas as pd
import sys

class MainFrame(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)

        data = [["A", "00:00:01", True, 0],
                ["B", "00:00:05", False, 1],
                ["C", "00:00:07", False, 2],
                ["D", "00:00:08", False, 3],
                ["E", "00:00:13", False, 2],
                ["F", "00:00:17", False, 1],
                ["G", "00:00:21", True, 0]]
        
        self.event_table = QtWidgets.QTableView()
        self.event_table.resizeRowsToContents()
        self.event_table.horizontalHeader().setStretchLastSection(True)
        
        df = pd.DataFrame(data, columns=["Event", "Time", "root", "Deepness"])
        self.model = EventTableModel(df)
        self.event_table.setModel(self.model)
        self.setCentralWidget(self.event_table)


class EventTableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super(EventTableModel, self).__init__()
        self._data = data
        self._color = QtGui.QBrush(QtGui.QColor(230, 230, 230))

    def data(self, index, role):
        if role ==  QtCore.Qt.DisplayRole:
            value = self._data.iloc[index.row(), index.column()]
            return str(value)
        
        if role == QtCore.Qt.BackgroundRole and index.row() % 2 == 0:
            #return QtGui.QBrush(QtGui.QColor(230, 230, 230))
            return self._color
    
    def headerData(self, section, orientation, role):
        # section is the index of the column/row.
        if role ==  QtCore.Qt.DisplayRole:
            if orientation ==  QtCore.Qt.Horizontal:
                return str(self._data.columns[section])

            if orientation ==  QtCore.Qt.Vertical:
                return str(self._data.index[section])

    def rowCount(self, index):
        return self._data.shape[0] 

    def columnCount(self, index):
        return self._data.shape[1]


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = MainFrame()
    main.show()
    sys.exit(app.exec_())
enyo
  • 41
  • 4
  • Is the model going to be editable, or could it change its structure? Becase, if not, there's probably no need to implement a model subclass and you could just create the structure using a QTreeWidget instead. I'm saying this because implementation tree models is not as easy as it might seem, and one should try to avoid that if not really necessary. – musicamante Nov 10 '20 at 14:42
  • @musicamante It shouldn't be editable and the structure doesn't change either – enyo Nov 10 '20 at 17:48

0 Answers0