<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[QTreeView + custom model issue with sorting]]></title><description><![CDATA[<p dir="auto">I need to display data in a single level tree structure (so they are appear like a simple list of items). The data come as list of dicts, like this</p>
<pre><code>data = [{"name": 1, "author": "user2", "created":"2023-10-31T12:40:22.083315Z", "attr":...}, {"name": 2, "author": "user1", "created":"2023-10-31T12:40:22.083315Z", "attr":...}...]
</code></pre>
<p dir="auto">To show this data in a tree view I have created a custom model</p>
<pre><code>class Node:
    def __init__(self, data={}):
        self.parent = None
        self.children = list()
        self.data = data
    
    def add_child_node(self, node):
        if node is None:
            return
    
        node.parent = self
        self.children.append(node)
    
    def delete_children(self):
        self.children.clear()
    
    def version(self):
        if self.data:
            return self.data.get("name")
        return None


class MyModel(QAbstractItemModel):
    VERSION = Qt.UserRole + 1
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.root_node = Node()
    
    def clear(self):
        self.beginResetModel()
        self.root_node.delete_children()
        self.endResetModel()
    
    def add_data(self, data):
        previous_row_count = self.rowCount()
        self.beginInsertRows(QModelIndex(), previous_row_count, previous_row_count)
        for i in data:
            node = Node(i)
            self.root_node.add_child_node(node)
        self.endInsertRows()
    
    def index2node(self, index):
        if not index.isValid():
            return self.root_node
    
        return index.internalPointer()
    
    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid():
            return None
    
        node = self.index2node(index)
        if role == Qt.DisplayRole:
            if index.column() == 0:
                return node.data["name"]
            elif index.column() == 1:
                return node.data["author"]
            elif index.column() == 2:
                return node.data["created"]
            else:
                return None
        elif role == Qt.ToolTipRole:
            if index.column() == 2:
                return node.data["created"]
        elif role == MyModel.VERSION:
            return node.data["name"]
        else:
            return None
    
    def headerData(self, section, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            if section == 0:
                return "Version"
            elif section == 1:
                return "Author"
            elif section == 2:
                return "Created"
            else:
                return None
        return None
    
    def rowCount(self, parent=QModelIndex()):
        node = self.index2node(parent)
        if node is None:
            return 0
    
        return len(node.children)
    
    def columnCount(self, parent=QModelIndex()):
        return 3
    
    def index(self, row, column, parent=QModelIndex()):
        if not self.hasIndex(row, column, parent):
            return QModelIndex()
    
        node = self.index2node(parent)
        if node is None:
            return QModelIndex()
    
        return self.createIndex(row, column, node.children[row])
    
    def parent(self, index):
        if not index.isValid():
            return QModelIndex()
    
        node = self.index2node(index)
        if node is not None:
            return self.index_of_parent_tree_node(node.parent)
        else:
            return QModelIndex()
    
    def index_of_parent_tree_node(self, parent_node):
        grand_parent_node = parent_node.parent
        if grand_parent_node is None:
            return QModelIndex()
    
        row = grand_parent_node.children.index(parent_node)
        return self.createIndex(row, 0, parent_node)
    
    def item_from_index(self, index):
        return self.index2node(index)
</code></pre>
<p dir="auto">The model is created and assigned to tree view, then populated by calling <code>add_data()</code> method whenever new portion of data arrived.</p>
<pre><code>model = MyModel()
tree.setModel(model)
...
model.add_data(data)
</code></pre>
<p dir="auto">This works fine and I have a tree view with three columns filled with information.</p>
<p dir="auto">But when I try to add sorting by using <code>QSortFilterProxyModel</code> only the first item is shown in the tree, even though the source model is populated correctly.</p>
<p dir="auto">Am I missing something in my model implementation or doing something wrong?</p>
]]></description><link>https://forum.qt.io/topic/151927/qtreeview-custom-model-issue-with-sorting</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Jul 2026 05:46:21 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/151927.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 07 Nov 2023 09:38:54 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to QTreeView + custom model issue with sorting on Tue, 07 Nov 2023 12:52:18 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/christian-ehrlicher">@<bdi>Christian-Ehrlicher</bdi></a> thanks for the pointer, changing call to</p>
<pre><code>self.beginInsertRows(QModelIndex(), previous_row_count, len(data))
</code></pre>
<p dir="auto">fixes it.</p>
]]></description><link>https://forum.qt.io/post/779025</link><guid isPermaLink="true">https://forum.qt.io/post/779025</guid><dc:creator><![CDATA[voltron]]></dc:creator><pubDate>Tue, 07 Nov 2023 12:52:18 GMT</pubDate></item><item><title><![CDATA[Reply to QTreeView + custom model issue with sorting on Tue, 07 Nov 2023 12:47:53 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> yes, for now proxy model does not filter/sort items. I just want to get them all shown correctly.</p>
]]></description><link>https://forum.qt.io/post/779023</link><guid isPermaLink="true">https://forum.qt.io/post/779023</guid><dc:creator><![CDATA[voltron]]></dc:creator><pubDate>Tue, 07 Nov 2023 12:47:53 GMT</pubDate></item><item><title><![CDATA[Reply to QTreeView + custom model issue with sorting on Tue, 07 Nov 2023 12:18:38 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/jonb">@<bdi>JonB</bdi></a> beginInsertRows() is called with wrong parameters.</p>
]]></description><link>https://forum.qt.io/post/779019</link><guid isPermaLink="true">https://forum.qt.io/post/779019</guid><dc:creator><![CDATA[Christian Ehrlicher]]></dc:creator><pubDate>Tue, 07 Nov 2023 12:18:38 GMT</pubDate></item><item><title><![CDATA[Reply to QTreeView + custom model issue with sorting on Tue, 07 Nov 2023 11:52:55 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/voltron">@<bdi>voltron</bdi></a> Start by checking how many items you have and what their parentage is <em>when accessed via the <code>QSortFilterProxyModel</code></em> indexes.  Also since you do not say I presume your QSFPM actually does neither filtering nor sorting currently?</p>
]]></description><link>https://forum.qt.io/post/779014</link><guid isPermaLink="true">https://forum.qt.io/post/779014</guid><dc:creator><![CDATA[JonB]]></dc:creator><pubDate>Tue, 07 Nov 2023 11:52:55 GMT</pubDate></item></channel></rss>