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_())
2
  • 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. Commented Nov 10, 2020 at 14:42
  • @musicamante It shouldn't be editable and the structure doesn't change either Commented Nov 10, 2020 at 17:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.