On Tue, Mar 10, 2009 at 8:03 PM, Darren Dale <dsdal...@gmail.com> wrote:
> On Tue, Mar 10, 2009 at 5:28 PM, Darren Dale <dsdal...@gmail.com> wrote: > >> Hello, >> >> I am trying to create a simple model and view for a simple nested >> dictionary like d: >> >> c1 = {'id':1, 'description':'child 1'} >> c2 = {'id':2, 'description':'child 2'} >> d = {'id':0, 'description':'whatever', 'children':[c1, c2]} >> >> I have a self-contained, relatively simple script attached. When I run it >> and try to open the top-level entry by clicking on the +, I get errors like: >> >> Traceback (most recent call last): >> File "tree_test.py", line 111, in parent >> parent = index.internalPointer().parent >> AttributeError: 'ItemDataRole' object has no attribute 'parent' >> Traceback (most recent call last): >> File "tree_test.py", line 111, in parent >> parent = index.internalPointer().parent >> AttributeError: parent >> >> Traceback (most recent call last): >> File "tree_test.py", line 111, in parent >> parent = index.internalPointer().parent >> AttributeError: 'exceptions.AttributeError' object has no attribute >> 'parent' >> Bus error >> >> sometimes I get a different error: >> >> Traceback (most recent call last): >> File "tree_test.py", line 111, in parent >> parent = index.internalPointer().parent >> AttributeError: 'ItemDataRole' object has no attribute 'parent' >> Segmentation fault >> >> >> Could anyone please help me understand what is happening? I dont >> understand why index.internalPointer() is returning an ItemDataRole object >> or an exceptions.AttributeError object. >> >> Im running Qt-4.5.0, sip-4.7.9 and PyQt-4.4.4. > > > I just checked this script on a 64-bit kubuntu intrepid system with > qt-4.4.3 and PyQt4-4.4.4, sip-4.7.9 and python-2.5.2 and I get segfaults > here too. I guess that rules out some issue specific to qt-4.5. > I've been looking into this some more, and I managed to isolate the problem. The attached script runs ok when CACHE_CHILDREN = True, but it will yield bus errors or segfaults when CACHE_CHILDREN is False. Unfortunately, I am modeling an object that can be changed elsewhere in the application, so it is imperitive that I am able to recalculate the child list. I have done the exact same thing using Enthought's Traits package with the Traits Qt4 backend, and never saw segfaults, so I know it must be possible. Please, can anyone suggest why this causes a crash? Thank you, Darren
""" """ from PyQt4 import QtCore, QtGui CACHE_CHILDREN = True class TreeItem(object): def __init__(self, data, parent=None): self._parent = parent self._data = data @property def children(self): return [] @property def columns(self): return [self.data['id'], self.data['description']] @property def data(self): return self._data @property def parent(self): return self._parent @property def row(self): if self.parent: return self.parent.children.index(self) return 0 @property def rows(self): return len(self.children) class RootItem(TreeItem): def __init__(self): self._parent = None self._children = [] @property def children(self): return self._children @property def columns(self): return ['ID', 'Description'] def appendChild(self, child): self._children.append(child) class DictItem(TreeItem): def __init__(self, data, parent=None): super(DictItem, self).__init__(data, parent) @property def children(self): if CACHE_CHILDREN: try: return self._children except AttributeError: self._children = [TreeItem(child, self) for child in self.data['children']] return self._children else: return [TreeItem(child, self) for child in self.data['children']] class FileModel(QtCore.QAbstractItemModel): """ """ def __init__(self, parent=None): super(FileModel, self).__init__(parent) self._rootItem = RootItem() @property def rootItem(self): return self._rootItem def columnCount(self, parent): if parent.isValid(): return len(parent.internalPointer().columns) else: return len(self.rootItem.columns) def data(self, index, role): if not index.isValid() or role != QtCore.Qt.DisplayRole: return QtCore.QVariant() item = index.internalPointer() return QtCore.QVariant(item.columns[index.column()]) def headerData(self, section, orientation, role): if orientation == QtCore.Qt.Horizontal and \ role == QtCore.Qt.DisplayRole: return QtCore.QVariant(self.rootItem.columns[section]) return QtCore.QVariant() def index(self, row, column, parent): if not self.hasIndex(row, column, parent): return QtCore.QModelIndex() if parent.isValid(): parentItem = parent.internalPointer() else: parentItem = self.rootItem child = parentItem.children[row] return self.createIndex(row, column, child) def parent(self, index): if not index.isValid(): return QtCore.QModelIndex() try: parent = index.internalPointer().parent if parent == self.rootItem or parent is None: return QtCore.QModelIndex() return self.createIndex(parent.row, 0, parent) except AttributeError: return QtCore.QModelIndex() def rowCount(self, parent): if parent.isValid(): parentItem = parent.internalPointer() else: parentItem = self.rootItem return parentItem.rows def appendDict(self, d): assert 'id' in d assert 'description' in d self.rootItem.appendChild(DictItem(d)) class FileView(QtGui.QTreeView): def __init__(self, model=None, parent=None): super(FileView, self).__init__(parent) self.setModel(model) if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) model = FileModel() form = FileView(model) c1 = {'id':1, 'description':'child 1'} c2 = {'id':2, 'description':'child 2'} d = {'id':0, 'description':'whatever', 'children':[c1, c2]} model.appendDict(d) form.show() sys.exit(app.exec_())
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt