Important: Please read the Qt Code of Conduct -

QTreeView with custom items

  • Hello,

    I'm writing my first Qt application with PySide and am having some trouble creating a custom tree view. I'd like to list my own data in one column. Each item must have text with tooltip, different text color, different background color, icons with actions and tooltip.

    The default tree works. I have view: class TreeView(PySide.QtGui.QTreeView): and model: class TreeModel(PySide.QtCore.QAbstractItemModel):

    How can I add different icons to my items?

    Here is my example:
    import sys
    from PySide import QtGui, QtCore

    class MyData():
    def init(self, txt, parent=None):
    self.txt = txt
    self.parent = parent
    self.child = []
    self.icon = None
    self.index = None

    def position(self):
        position = 0
        if self.parent is not None:
            count = 0
            children = self.parent.child
            for child in children:
                if child == self:
                    position = count
                count += 1
        return position
    def init():
        root = MyData("root")
        for i in range(0, 2):
            child1 = MyData("child %i" % (i), root)
            for x in range(0, 2):
                child2 = MyData("child %i %i" % (i, x), child1)
        return root

    class TreeModel(QtCore.QAbstractItemModel):
    def init(self, tree):
    super(TreeModel, self).init()
    self.__tree = tree
    self.__current = tree

    def flags(self, index):
        flag = QtCore.Qt.ItemIsEnabled
        if index.isValid():
            flag |= QtCore.Qt.ItemIsSelectable \
                 | QtCore.Qt.ItemIsUserCheckable \
                 | QtCore.Qt.ItemIsEditable \
                 | QtCore.Qt.ItemIsDragEnabled \
                 | QtCore.Qt.ItemIsDropEnabled
        return flag
    def index(self, row, column, parent=QtCore.QModelIndex()):
        node = QtCore.QModelIndex()
        if parent.isValid():
            nodeS = parent.internalPointer()
            nodeX = nodeS.child[row]
            node = self.__createIndex(row, column, nodeX)
            node = self.__createIndex(row, column, self.__tree)
        return node
    def parent(self, index):
        node = QtCore.QModelIndex()
        if index.isValid():
            nodeS = index.internalPointer()
            parent = nodeS.parent
            if parent is not None:
                node = self.__createIndex(parent.position(), 0, parent)
        return node
    def rowCount(self, index=QtCore.QModelIndex()):
        count = 1
        node = index.internalPointer()
        if node is not None:
            count = len(node.child)
        return count
    def columnCount(self, index=QtCore.QModelIndex()):
        return 1
    def data(self, index, role=QtCore.Qt.DisplayRole):
        data = None
        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            node = index.internalPointer()
            data = node.txt
        if role == QtCore.Qt.ToolTipRole:
            node = index.internalPointer()
            data = "ToolTip " + node.txt
        if role == QtCore.Qt.DecorationRole:
            data = QtGui.QIcon("icon.png")
        return data
    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        result = True
        if role == QtCore.Qt.EditRole and value != "":
            node = index.internalPointer()
            node.text = value
            result = True
        return result
    def __createIndex(self, row, column, node):
        if node.index == None:
            index = self.createIndex(row, column, node)
            node.index = index
            icon = QtGui.QIcon("icon.png")
            b = self.setData(index, icon, QtCore.Qt.DecorationRole)
            b = self.setData(index, "ToolTip "+node.txt, QtCore.Qt.ToolTipRole)
        return node.index

    class TreeView(QtGui.QTreeView):
    def init(self, model, parent=None):
    super(TreeView, self).init(parent)
    self.setCurrentIndex(model.index(0, 0))

    class MyTree(QtGui.QMainWindow):
    def init(self, parent=None):
    super(MyTree, self).init(parent)
    data = MyData.init()
    treeModel = TreeModel(data)
    treeView = TreeView(treeModel)

    def main():
    app = QtGui.QApplication(sys.argv)
    form = MyTree()

    if name == 'main':

  • Hello,
    Even if this concern is far behind you now, did you find the solution to the needs you expressed ?
    I have exactly the same concern and i don't find enough complex examples of code in Qt documentation.
    Is it possible that you can provide here the code that fulfill your needs ?
    Thanks in advance,

  • @padec
    The OP asked:

    How can I add different icons to my items?

    So for that did you look at your model's override of QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const? When that is called with role == Qt::DecorationRole shows:

    Qt::DecorationRole 1 The data to be rendered as a decoration in the form of an icon. (QColor, QIcon or QPixmap)

    Did you handle this and return your desired icon for the index passed in?

  • @JonB Thanks for your reply. Yes i think that i understand the principle.
    As i have nearly the same Python code to write, i was looking for an already validated code to speed up my development and its debug.

Log in to reply