Re: [PyQt] Re: seeking advice on why this script segfaults
On Thu, Mar 12, 2009 at 2:57 PM, Arnold Krille wrote: > On Thursday 12 March 2009 17:31:40 Darren Dale wrote: > > If anybody has some example of a working QAbstractItemModel/QTreeView for > > dynamic data, would you please consider posting it (if its short) or > > sending it to me off list? I've been working on this problem for days now > > and I'm not getting anywhere. > > I don't know what you mean with dynamic data, On Thu, Mar 12, 2009 at 2:57 PM, Arnold Krille wrote: > On Thursday 12 March 2009 17:31:40 Darren Dale wrote: > > If anybody has some example of a working QAbstractItemModel/QTreeView for > > dynamic data, would you please consider posting it (if its short) or > > sending it to me off list? I've been working on this problem for days now > > and I'm not getting anywhere. > > I don't know what you mean with dynamic data, but I have trees that fill > themselves at runtime upon user interaction. And have children of different > kinds... > I am modeling data in a file that is organized in an hierarchy very similar to directories and files in a file system, and the structure of that hierarchy is changed not through the tree view, but elsewhere in the application. I managed to put together a workaround, based on the hasChildren/canFetchMore/fetchMore infrastructure to lazily populate the list of nodes when expanding, and connecting the TreeView collapsed signal to a method that clears the list of nodes so the list can be refreshed when it is re-expanded. It still feels like I've overlooked something or I'm not using the provided tools effectively, but its sufficient for me to get by for now and I'm under a deadline. Would it be possible to add some kind of check to raise an error and prevent PyQt from segfaulting with the original script? Darren """ """ from PyQt4 import QtCore, QtGui from functools import wraps import time class TreeItem(object): def __init__(self, data, parent=None): self._parent = parent self._data = data self._children = [] @property def children(self): return self._children @property def columns(self): return [self.data['id'], self.data['description']] @property def data(self): return self._data @property def hasChildren(self): return False @property def parent(self): return self._parent @property def row(self): if self.parent: return self.parent.children.index(self) return 0 def clearChildren(self): self._children = [] def __len__(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'] @property def hasChildren(self): return True 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 not self._children: self._children = [TreeItem(child, self) for child in self.data['children']] return self._children @property def hasChildren(self): return True 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 canFetchMore(self, index): parentItem = index.internalPointer() if parentItem is not None: return len(parentItem) == 0 else: return False 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 fetchMore(self, index): parentItem = index.internalPointer() if parentItem is not None: self.beginInsertRows(index, 0, len(parentItem)) parentItem.children self.endInsertRows() def hasChildren(self, index): parentItem = index.internalPointer() if parentItem is not None: return parentItem.hasChildren else: return True 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, ro
Re: [PyQt] Re: seeking advice on why this script segfaults
On Thursday 12 March 2009 17:31:40 Darren Dale wrote: > If anybody has some example of a working QAbstractItemModel/QTreeView for > dynamic data, would you please consider posting it (if its short) or > sending it to me off list? I've been working on this problem for days now > and I'm not getting anywhere. I don't know what you mean with dynamic data, but I have trees that fill themselves at runtime upon user interaction. And have children of different kinds... (I am sorry to link you to the trac, the source tarball of the new 0.5 version isn't ready yet as 0.5 isn't ready yet.) At https://svn.fzd.de/trac/epos/browser/trunk/epos/libcore you can find qtreeitem.* which is the abstract tree base-class I use for the C++ tree, qtreeitemmodel.* is the model to display tree of this type. (For the full functionality of the qtreeitem you need the delegate from our libgui.) And at https://svn.fzd.de/trac/epos/browser/trunk/sqeconv in the abstractconvertermodel.py there is a proxymodel that has parameters. And these are displayed by ConverterActionsModel in sqeconv itself. Maybe that helps you, Arnold signature.asc Description: This is a digitally signed message part. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Re: seeking advice on why this script segfaults
On Wed, Mar 11, 2009 at 11:56 AM, Darren Dale wrote: > On Tue, Mar 10, 2009 at 8:03 PM, Darren Dale wrote: > >> On Tue, Mar 10, 2009 at 5:28 PM, Darren Dale 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? > If anybody has some example of a working QAbstractItemModel/QTreeView for dynamic data, would you please consider posting it (if its short) or sending it to me off list? I've been working on this problem for days now and I'm not getting anywhere. Thank you, Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Re: seeking advice on why this script segfaults
On Tue, Mar 10, 2009 at 8:03 PM, Darren Dale wrote: > On Tue, Mar 10, 2009 at 5:28 PM, Darren Dale 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):
[PyQt] Re: seeking advice on why this script segfaults
On Tue, Mar 10, 2009 at 5:28 PM, Darren Dale 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. Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt