<div dir="ltr"><div>Hi Florian,</div><div><br></div><div>Thanks much for the response. It's a big project and I tried my best to extract only the required portion of it. Here's the source code for you to look at. It actually involves getting folder tree structure from server and displaying it with checkboxes that allows the user to choose a sub-set from it.</div><div><br></div><div>Whenever the user expands we get the children from server and add it to the tree. Our app crashes when we do exactly this.</div><div><br></div><div>In the documentation of pytest-qt it's said that we need to add some items and then test. Does it mean after appending few children at the root level? Thanks again.</div><div><br></div><div><pre style="margin-top:0px;margin-bottom:1em;padding:5px;border:0px;font-variant-numeric:inherit;font-stretch:inherit;font-size:13px;line-height:inherit;font-family:Consolas,Menlo,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace,sans-serif;vertical-align:baseline;width:auto;max-height:600px;overflow:auto;background-color:rgb(239,240,241);word-wrap:normal;color:rgb(36,39,41)"><code style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:Consolas,Menlo,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace,sans-serif;vertical-align:baseline;white-space:inherit">self.model.beginInsertRows(index,1,2)
childItem = TreeItem("idxx", "Namexx", "idxy", "idxz", parent=index.internalPointer())
index.internalPointer().appendChild(childItem)
self.model.endInsertRows()</code></pre></div><div><br></div><div><br></div><div><pre style="margin-top:0px;margin-bottom:1em;padding:5px;border:0px;font-variant-numeric:inherit;font-stretch:inherit;font-size:13px;line-height:inherit;font-family:Consolas,Menlo,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace,sans-serif;vertical-align:baseline;width:auto;max-height:600px;overflow:auto;background-color:rgb(239,240,241);word-wrap:normal;color:rgb(36,39,41)"><code style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:Consolas,Menlo,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace,sans-serif;vertical-align:baseline;white-space:inherit">from PyQt5.QtWidgets import QApplication, QTreeView, QWidget, QStyle
from PyQt5.QtCore import QModelIndex, QAbstractItemModel
from PyQt5.Qt import Qt, pyqtSignal

import traceback

LOADING_IN_PROGRESS="Loading"

class TreeItem(object):
    def __init__(self, resource_id, name, parent_id, root_id, parent=None, type="Folder"):
        self.resource_id = resource_id
        self.parent_id = parent_id
        self.root_id = root_id
        self.parentItem = parent
        <a href="http://self.name">self.name</a>= name
        self.nodeType=type
        self.childItems = []

        self.populated = None
        self.hasChildren = True

        self.checkState = Qt.Checked

    def insertChild(self, pos, item):
        self.childItems.insert(pos, item)

    def appendChild(self, item):
        self.childItems.append(item)

    def removeChild(self, item):
        self.childItems.pop(0)

    def child(self, row):
        return self.childItems[row]

    def childCount(self):
        return len(self.childItems)

    def data(self, column):
        try:
            return <a href="http://self.name">self.name</a>
        except IndexError:
            return None

    def parent(self):
        return self.parentItem

    def row(self):
        if self.parentItem:
            return self.parentItem.childItems.index(self)
        return 0

class TreeModel(QAbstractItemModel):
    inProgress = pyqtSignal(str,str)
    def __init__(self, parentDialog):
        super().__init__(parent=None)
        self.checks = {}

        self.widget=QWidget()
        self.parentCls = parentDialog
        self.rootItem = parentDialog.rootItem
        self.dbHandle = parentDialog.dbhandle

    def hasChildren(self,index):
        return True

    def columnCount(self, parent):
        return 1

    def data(self, index, role):
        try:
            if not index.isValid():
                return None

            if role == Qt.CheckStateRole:
                if index.column() == 0:
                    if index.internalPointer().resource_id==LOADING_IN_PROGRESS:
                        return None
                    else:
                        return self.getCheckState(index)

            elif role == Qt.DecorationRole:
                if index.internalPointer().resource_id==LOADING_IN_PROGRESS:
                    return None
                else:
                    return self.widget.style().standardIcon(QStyle.SP_DirIcon)

            elif role == Qt.DisplayRole:
                item = index.internalPointer()
                return item.data(index.column())

            elif role == Qt.UserRole:
                uniqueId = index.internalPointer().resource_id+index.internalPointer().root_id
                return uniqueId

            else:
                return None
        except Exception as err:
            traceback.print_exc()

    def getCheckState(self, index):
        if index.isValid():
            return index.internalPointer().checkState

    def setData(self, index, value, role):
        try:
            if not index.isValid():
                return None
            if index.internalPointer().resource_id!=LOADING_IN_PROGRESS and (role == Qt.CheckStateRole and index.column() == 0):
                #self.checks[index] = value

                if (value ==  Qt.Unchecked and not
                    self.db.can_uncheck(index.internalPointer().resource_id)):
                    if index.internalPointer().checkState:
                        self.inProgress.emit(index.internalPointer().resource_id,index.internalPointer().root_id)
                    return True

                index.internalPointer().checkState = value

                if value== Qt.PartiallyChecked:
                    self.dataChanged.emit(index,index)
                    return True

                for i in range(self.rowCount(index)):
                    child=self.index(i, 0, index)
                    if child.internalPointer().resource_id!=LOADING_IN_PROGRESS:
                        self.setData(child, value, Qt.CheckStateRole)

                if value ==  Qt.Unchecked:
                    parent  =   self.parent(index)

                    while parent.isValid() and self.data(parent, Qt.CheckStateRole) == Qt.Checked:
                        self.setData(parent, Qt.PartiallyChecked, Qt.CheckStateRole)
                        #parent.setCheckState(column, QtCore.Qt.PartiallyChecked)
                        parent  =   parent.parent()

                else:
                    parent  =   self.parent(index)
                    while parent.isValid():
#                        ispartial = not all(self.data(parent, QtCore.Qt.CheckStateRole)==value for i in range(self.rowCount(parent)) if parent.isValid())
                        ispartial=False
                        for i in range(self.rowCount(parent)):
                            child=self.index(i, 0, parent)
                            if child.internalPointer().resource_id!=LOADING_IN_PROGRESS:
                                if self.data(child, Qt.CheckStateRole)!=value:
                                    ispartial=True
                                    break

                        newstate =   [value, Qt.PartiallyChecked][ispartial]
                        #parent.setCheckState(value, newstate)
                        if self.data(parent, Qt.CheckStateRole)!=newstate:
                            self.setData(parent, newstate, Qt.CheckStateRole)
                        parent  =   parent.parent()

                self.dataChanged.emit(index,index)
                return True

            return super().setData(index, value, role)
        except Exception as err:
            traceback.print_exc()

    def flags(self, index):
        try:
            flags=super().flags(index) #|QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
            if not index.isValid():
                return Qt.NoItemFlags
            if index.internalPointer().resource_id == LOADING_IN_PROGRESS:
                return flags & ~Qt.ItemIsUserCheckable & ~Qt.ItemIsEnabled
            return flags|Qt.ItemIsUserCheckable
        except Exception as err:
            traceback.print_exc()

    def headerData(self, section, orientation, role):
        return None

    def index(self, row, column, parent):
        try:
            if not self.hasIndex(row, column, parent):
                return QModelIndex()

            if not parent.isValid():
                parentItem = self.rootItem
            else:
                parentItem = parent.internalPointer()

            childItem = parentItem.child(row)
            if childItem:
                return self.createIndex(row, column, childItem)
            else:
                return QModelIndex()
        except Exception as err:
            traceback.print_exc()

    def parent(self, index):
        try:
            if not index.isValid():
                return QModelIndex()

            childItem = index.internalPointer()
            parentItem = childItem.parent()

            if parentItem == self.rootItem:
                return QModelIndex()

            return self.createIndex(parentItem.row(), 0, parentItem)
        except Exception as err:
            traceback.print_exc()

    def rowCount(self, parent):
        try:
            if parent.column() > 0:
                return 0
            if not parent.isValid():
                parentItem = self.rootItem
            else:
                parentItem = parent.internalPointer()
            return parentItem.childCount()
        except Exception as err:
            traceback.print_exc()</code></pre></div><br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
On Fri, May 19, 2017 at 03:25:21PM +0530, Rathinam Signup wrote:<br>
> I'm using QAbstractItemModel with QTreeView in PyQt5.6-Py3.5. When I call<br>
> model.beginInsertRows(index,i,<wbr>i) the app crashes. If I try to add children<br>
> under root index it's working fine. But If I try to add rows on any other<br>
> index the app crashes. I'm quite sure that it worked without any issues in<br>
> PyQt4.<br>
><br>
> Any help would be appreciated. Thanks.<br>
<br>
Without seeing any code, we can't really tell you much more than the<br>
segfault already does: Probably there's *something* wrong with your code<br>
;-)<br>
<br>
I suggest trying to run the pytest-qt modeltester over your model:<br>
<a href="http://pytest-qt.readthedocs.io/en/latest/modeltester.html" rel="noreferrer" target="_blank">http://pytest-qt.readthedocs.<wbr>io/en/latest/modeltester.html</a><br>
<br>
Florian<br>
</blockquote></div><br></div></div>