Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
On Thu, Apr 23, 2009 at 12:28 PM, Darren Dale wrote: > > > On Mon, Apr 13, 2009 at 3:43 PM, Darren Dale wrote: > >> >> >> On Mon, Apr 13, 2009 at 3:11 PM, Andreas Pakulat wrote: >> >>> On 13.04.09 10:27:56, Darren Dale wrote: >>> > On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat wrote: >>> > > On 13.04.09 14:11:46, Arnold Krille wrote: >>> > > > It is a pointer for internal purposes, that is internal for the >>> model >>> > > > so it can map indexes to the internal data structures. (And yes, >>> that >>> > > > is needed for anything except simple list or table models.:) >>> > > >>> > > Thats not true actually, you can create the most complex >>> model >>> > > imaginable without using the internalPointer, simply by using the >>> > > internalId and the related createIndex overload. That also >>> automatically >>> > > solves any problems created by python's refcounting+garbage >>> collection >>> > > (if you forget to store a reference to an object for the model in >>> your >>> > > model) >>> > >>> > Could you please sugggest an example of this approach, if you know of >>> one? >>> >>> Thats easy, provide some way of hashing the objects in your tree, then >>> use the hashnumber for the internal id. Often using id(yourobject) works >>> quite well as internal id. Then all you need is a dict using the id as >>> key and the real object as value, so you can easily look your object up. >>> Or maybe your internal data layout already orders the objects in some >>> way, then the searching through that tree might be efficiently possible >>> and you don't need the dict at all. I don't have a pyqt source tree >>> here, but I think the tree model example uses internalId for storing and >>> identifier for each object. >>> >> >> Ok, I think I get it, thank you. When I get time, I'll improve the example >> I posted in the other thread and share it with the list. >> > > I'm sorry, I think I need to ask for a little more clarification. After > failing to convert my own code to use InternalId() instead of > internalPointer, I decided it would be more instructive to convert the > simpletreemodel example distributed with PyQt4 to use internalId. I am > attaching that example, which fails with the repeated errors below. Could > anyone have a look and suggest how it should be improved? It requires other > files that ship with the original PyQt4 simpletreemodel example. > > Thanks, > Darren > > Traceback (most recent call last): > File "simpletreemodel.py", line 124, in parent > childItem = self.idMap[index.internalId()] > KeyError: 754744568L > Traceback (most recent call last): > File "simpletreemodel.py", line 124, in parent > childItem = self.idMap[index.internalId()] > KeyError: 754744568L > Traceback (most recent call last): > File "simpletreemodel.py", line 124, in parent > childItem = self.idMap[index.internalId()] > KeyError: 754744568L > Traceback (most recent call last): > File "simpletreemodel.py", line 139, in rowCount > parentItem = self.idMap[parent.internalId()] > KeyError: 754744568L > Traceback (most recent call last): > File "simpletreemodel.py", line 89, in data > item = self.idMap[index.internalId()] > KeyError: 754744568L > Traceback (most recent call last): > File "simpletreemodel.py", line 89, in data > item = self.idMap[index.internalId()] > KeyError: 754744568L > I was confused about how QModelIndex works, I thought passing a hash to createIndex meant that the hash was the index's internalId, but that is not the case. So I was using the hash as my idMap key, when I should have been using internalId. Here is a working script. #!/usr/bin/env python """*** ** ** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. ** ** This file is part of the example classes of the Qt Toolkit. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sa...@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ***""" import sys from PyQt4 import QtCore, QtGui import simpletreemodel_rc class TreeItem: def __init__(self, data, parent=None): self.parentItem = parent self.itemData = data self.childItems = [] def appendChild(self, item): self.childItems.appe
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
On Mon, Apr 13, 2009 at 3:43 PM, Darren Dale wrote: > > > On Mon, Apr 13, 2009 at 3:11 PM, Andreas Pakulat wrote: > >> On 13.04.09 10:27:56, Darren Dale wrote: >> > On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat wrote: >> > > On 13.04.09 14:11:46, Arnold Krille wrote: >> > > > It is a pointer for internal purposes, that is internal for the >> model >> > > > so it can map indexes to the internal data structures. (And yes, >> that >> > > > is needed for anything except simple list or table models.:) >> > > >> > > Thats not true actually, you can create the most complex >> model >> > > imaginable without using the internalPointer, simply by using the >> > > internalId and the related createIndex overload. That also >> automatically >> > > solves any problems created by python's refcounting+garbage collection >> > > (if you forget to store a reference to an object for the model in your >> > > model) >> > >> > Could you please sugggest an example of this approach, if you know of >> one? >> >> Thats easy, provide some way of hashing the objects in your tree, then >> use the hashnumber for the internal id. Often using id(yourobject) works >> quite well as internal id. Then all you need is a dict using the id as >> key and the real object as value, so you can easily look your object up. >> Or maybe your internal data layout already orders the objects in some >> way, then the searching through that tree might be efficiently possible >> and you don't need the dict at all. I don't have a pyqt source tree >> here, but I think the tree model example uses internalId for storing and >> identifier for each object. >> > > Ok, I think I get it, thank you. When I get time, I'll improve the example > I posted in the other thread and share it with the list. > I'm sorry, I think I need to ask for a little more clarification. After failing to convert my own code to use InternalId() instead of internalPointer, I decided it would be more instructive to convert the simpletreemodel example distributed with PyQt4 to use internalId. I am attaching that example, which fails with the repeated errors below. Could anyone have a look and suggest how it should be improved? It requires other files that ship with the original PyQt4 simpletreemodel example. Thanks, Darren Traceback (most recent call last): File "simpletreemodel.py", line 124, in parent childItem = self.idMap[index.internalId()] KeyError: 754744568L Traceback (most recent call last): File "simpletreemodel.py", line 124, in parent childItem = self.idMap[index.internalId()] KeyError: 754744568L Traceback (most recent call last): File "simpletreemodel.py", line 124, in parent childItem = self.idMap[index.internalId()] KeyError: 754744568L Traceback (most recent call last): File "simpletreemodel.py", line 139, in rowCount parentItem = self.idMap[parent.internalId()] KeyError: 754744568L Traceback (most recent call last): File "simpletreemodel.py", line 89, in data item = self.idMap[index.internalId()] KeyError: 754744568L Traceback (most recent call last): File "simpletreemodel.py", line 89, in data item = self.idMap[index.internalId()] KeyError: 754744568L #!/usr/bin/env python """*** ** ** Copyright (C) 2005-2005 Trolltech AS. All rights reserved. ** ** This file is part of the example classes of the Qt Toolkit. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://www.trolltech.com/products/qt/opensource.html ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://www.trolltech.com/products/qt/licensing.html or contact the ** sales department at sa...@trolltech.com. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ***""" import sys from PyQt4 import QtCore, QtGui import simpletreemodel_rc class TreeItem: def __init__(self, data, parent=None): self.parentItem = parent self.itemData = data self.childItems = [] def appendChild(self, item): self.childItems.append(item) def child(self, row): return self.childItems[row] def childCount(self): return len(self.childItems) def columnCount(self): return len(self.itemData) def data(self, column): return self.itemData[column] def parent(self): return self.parentItem def row(self): if self.parentItem: return self.parentItem.childItems.index(self) return 0 class
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
On Mon, Apr 13, 2009 at 3:11 PM, Andreas Pakulat wrote: > On 13.04.09 10:27:56, Darren Dale wrote: > > On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat wrote: > > > On 13.04.09 14:11:46, Arnold Krille wrote: > > > > It is a pointer for internal purposes, that is internal for the model > > > > so it can map indexes to the internal data structures. (And yes, that > > > > is needed for anything except simple list or table models.:) > > > > > > Thats not true actually, you can create the most complex model > > > imaginable without using the internalPointer, simply by using the > > > internalId and the related createIndex overload. That also > automatically > > > solves any problems created by python's refcounting+garbage collection > > > (if you forget to store a reference to an object for the model in your > > > model) > > > > Could you please sugggest an example of this approach, if you know of > one? > > Thats easy, provide some way of hashing the objects in your tree, then > use the hashnumber for the internal id. Often using id(yourobject) works > quite well as internal id. Then all you need is a dict using the id as > key and the real object as value, so you can easily look your object up. > Or maybe your internal data layout already orders the objects in some > way, then the searching through that tree might be efficiently possible > and you don't need the dict at all. I don't have a pyqt source tree > here, but I think the tree model example uses internalId for storing and > identifier for each object. > Ok, I think I get it, thank you. When I get time, I'll improve the example I posted in the other thread and share it with the list. Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
On 13.04.09 10:27:56, Darren Dale wrote: > On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat wrote: > > On 13.04.09 14:11:46, Arnold Krille wrote: > > > It is a pointer for internal purposes, that is internal for the model > > > so it can map indexes to the internal data structures. (And yes, that > > > is needed for anything except simple list or table models.:) > > > > Thats not true actually, you can create the most complex model > > imaginable without using the internalPointer, simply by using the > > internalId and the related createIndex overload. That also automatically > > solves any problems created by python's refcounting+garbage collection > > (if you forget to store a reference to an object for the model in your > > model) > > Could you please sugggest an example of this approach, if you know of one? Thats easy, provide some way of hashing the objects in your tree, then use the hashnumber for the internal id. Often using id(yourobject) works quite well as internal id. Then all you need is a dict using the id as key and the real object as value, so you can easily look your object up. Or maybe your internal data layout already orders the objects in some way, then the searching through that tree might be efficiently possible and you don't need the dict at all. I don't have a pyqt source tree here, but I think the tree model example uses internalId for storing and identifier for each object. Andreas -- Lady Luck brings added income today. Lady friend takes it away tonight. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
Hi Andreas, On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat wrote: > On 13.04.09 14:11:46, Arnold Krille wrote: > > It is a pointer for internal purposes, that is internal for the model > > so it can map indexes to the internal data structures. (And yes, that > > is needed for anything except simple list or table models.:) > > Thats not true actually, you can create the most complex model > imaginable without using the internalPointer, simply by using the > internalId and the related createIndex overload. That also automatically > solves any problems created by python's refcounting+garbage collection > (if you forget to store a reference to an object for the model in your > model) > Could you please sugggest an example of this approach, if you know of one? I started a thread on March 10 on this mailing list ("seeking advice on why this script segfaults") where I put together an unsatisfying work around to avoid segfaults that were probably caused by my use of internalPointer. Thanks, Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
On 13.04.09 14:11:46, Arnold Krille wrote: > It is a pointer for internal purposes, that is internal for the model > so it can map indexes to the internal data structures. (And yes, that > is needed for anything except simple list or table models.:) Thats not true actually, you can create the most complex model imaginable without using the internalPointer, simply by using the internalId and the related createIndex overload. That also automatically solves any problems created by python's refcounting+garbage collection (if you forget to store a reference to an object for the model in your model) Andreas -- Your aim is high and to the right. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
Hi, On Thursday 09 April 2009 19:35:32 TP wrote: > Here are the most important lines: > self.view = QTreeView( parent ) > self.connect( self.view, SIGNAL( "clicked(QModelIndex)" ) > , self.cellClicked ) > def cellClicked( self, qmodelindex ): > if qmodelindex.isValid(): > print qmodelindex.internalPointer() > The problem seems to be related to qmodelindex, the segfault appears when > taking internalPointer method. I think there is a very good reason internalPointer has the name it has. It is a pointer for internal purposes, that is internal for the model so it can map indexes to the internal data structures. (And yes, that is needed for anything except simple list or table models.:) You shouldn't really access it from a view (or from a proxy-model). Actually the reason for the model-view-pattern is that you don't have to access the internal structures of the model from the view... And here is another reason this crashes: Not only don't you know which type (if any) the object pointed to is, you also don't know whether python knows about that data type (python doesn't really know about pointers). Have fun, Arnold signature.asc Description: This is a digitally signed message part. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
Why do you need access to the QModelIndex internal pointer? It sounds like you are trying to access a null pointer, causing a crash. Looking at the signature, ptr is some sort of id or extra data associated with the index, which you probably need to add yourself when creating an index. QModelIndex QAbstractItemModel::createIndex ( int row, int column, void * ptr = 0 ) const [protected] TP-5 wrote: > > TP a écrit : >> Could this be a bug in PyQt? > > Has someone tried my script to check if the segfault is reproducible? > > Julien > > ___ > PyQt mailing listPyQt@riverbankcomputing.com > http://www.riverbankcomputing.com/mailman/listinfo/pyqt > > -- View this message in context: http://www.nabble.com/segfault-when-using-a-proxy-and-SIGNAL%28-%22clicked%28QModelIndex%29%22-%29-tp22977318p23006807.html Sent from the PyQt mailing list archive at Nabble.com. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] segfault when using a proxy and SIGNAL( "clicked(QModelIndex)" )
Hi everybody, Here you will find a small (170 lines) self-contained Python script. http://paratribulations.free.fr/help/python/simpleproxy.py I use a model, and a proxy (that does nothing, but in a more complicated version, not given here, it works perfectly). The view is a QTreeView. The problem appears when I connect the SIGNAL( "clicked(QModelIndex)" ) to some method "cellClicked" in the view, I obtain segfaults. Difficult for me to find the problem. Here are the most important lines: self.view = QTreeView( parent ) self.connect( self.view, SIGNAL( "clicked(QModelIndex)" ) , self.cellClicked ) def cellClicked( self, qmodelindex ): if qmodelindex.isValid(): print qmodelindex.internalPointer() The problem seems to be related to qmodelindex, the segfault appears when taking internalPointer method. Any idea? Thanks a lot. Julien -- python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\ 9&1+,\'Z4(55l4('])" "When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong." (first law of AC Clarke) ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt