On Mon, Apr 13, 2009 at 3:43 PM, Darren Dale <[email protected]> wrote:
> > > On Mon, Apr 13, 2009 at 3:11 PM, Andreas Pakulat <[email protected]> wrote: > >> On 13.04.09 10:27:56, Darren Dale wrote: >> > On Mon, Apr 13, 2009 at 9:58 AM, Andreas Pakulat <[email protected]> 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.:) >> > > >> > > <nitpick>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 [email protected]. ** ** 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 TreeModel(QtCore.QAbstractItemModel): def __init__(self, data, parent=None): QtCore.QAbstractItemModel.__init__(self, parent) self.idMap = {} rootData = [] rootData.append(QtCore.QVariant("Title")) rootData.append(QtCore.QVariant("Summary")) self.rootItem = TreeItem(rootData) self.idMap[id(self.rootItem)] = self.rootItem self.setupModelData(data.split("\n"), self.rootItem) def columnCount(self, parent): if parent.isValid(): return self.idMap[parent.internalId()].columnCount() else: return self.rootItem.columnCount() def data(self, index, role): if not index.isValid(): return QtCore.QVariant() if role != QtCore.Qt.DisplayRole: return QtCore.QVariant() item = self.idMap[index.internalId()] return QtCore.QVariant(item.data(index.column())) def flags(self, index): if not index.isValid(): return QtCore.Qt.ItemIsEnabled return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable def headerData(self, section, orientation, role): if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: return self.rootItem.data(section) return QtCore.QVariant() def index(self, row, column, parent): if row < 0 or column < 0 or row >= self.rowCount(parent) or column >= self.columnCount(parent): return QtCore.QModelIndex() if not parent.isValid(): parentItem = self.rootItem else: parentItem = self.idMap[parent.internalId()] childItem = parentItem.child(row) if childItem: return self.createIndex(row, column, id(childItem)) else: return QtCore.QModelIndex() def parent(self, index): if not index.isValid(): return QtCore.QModelIndex() childItem = self.idMap[index.internalId()] parentItem = childItem.parent() if parentItem == self.rootItem: return QtCore.QModelIndex() return self.createIndex(parentItem.row(), 0, id(parentItem)) def rowCount(self, parent): if parent.column() > 0: return 0 if not parent.isValid(): parentItem = self.rootItem else: parentItem = self.idMap[parent.internalId()] return parentItem.childCount() def setupModelData(self, lines, parent): parents = [] indentations = [] parents.append(parent) indentations.append(0) number = 0 while number < len(lines): position = 0 while position < len(lines[number]): if lines[number][position] != " ": break position += 1 lineData = lines[number][position:].trimmed() if not lineData.isEmpty(): # Read the column data from the rest of the line. columnStrings = lineData.split("\t", QtCore.QString.SkipEmptyParts) columnData = [] for column in range(0, len(columnStrings)): columnData.append(columnStrings[column]) if position > indentations[-1]: # The last child of the current parent is now the new parent # unless the current parent has no children. if parents[-1].childCount() > 0: parents.append(parents[-1].child(parents[-1].childCount() - 1)) indentations.append(position) else: while position < indentations[-1] and len(parents) > 0: parents.pop() indentations.pop() # Append a new item to the current parent's list of children. item = TreeItem(columnData, parents[-1]) self.idMap[id(item)] = item parents[-1].appendChild(item) number += 1 if __name__ == "__main__": app = QtGui.QApplication(sys.argv) f = QtCore.QFile(":/default.txt") f.open(QtCore.QIODevice.ReadOnly) model = TreeModel(QtCore.QString(f.readAll())) f.close() view = QtGui.QTreeView() view.setModel(model) view.setWindowTitle("Simple Tree Model") view.show() sys.exit(app.exec_())
_______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
