[PyQt] PyQt5.6 with Python 3.5 Crash

Rathinam Signup tfa.signup.test at gmail.com
Fri May 19 12:51:28 BST 2017


Hi Florian,

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.

Whenever the user expands we get the children from server and add it to the
tree. Our app crashes when we do exactly this.

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.

self.model.beginInsertRows(index,1,2)
childItem = TreeItem("idxx", "Namexx", "idxy", "idxz",
parent=index.internalPointer())
index.internalPointer().appendChild(childItem)
self.model.endInsertRows()



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
        self.name= 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 self.name
        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()


Hi,
>
> On Fri, May 19, 2017 at 03:25:21PM +0530, Rathinam Signup wrote:
> > I'm using QAbstractItemModel with QTreeView in PyQt5.6-Py3.5. When I call
> > model.beginInsertRows(index,i,i) the app crashes. If I try to add
> children
> > under root index it's working fine. But If I try to add rows on any other
> > index the app crashes. I'm quite sure that it worked without any issues
> in
> > PyQt4.
> >
> > Any help would be appreciated. Thanks.
>
> Without seeing any code, we can't really tell you much more than the
> segfault already does: Probably there's *something* wrong with your code
> ;-)
>
> I suggest trying to run the pytest-qt modeltester over your model:
> http://pytest-qt.readthedocs.io/en/latest/modeltester.html
>
> Florian
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20170519/00190c3c/attachment.html>


More information about the PyQt mailing list