[PyQt] QTreeView: inserting and removing rows in view and underlying data...

Andreas Pakulat apaku at gmx.de
Fri Nov 9 10:35:22 GMT 2007


On 09.11.07 10:58:08, Dirk Wagener wrote:
> I am confused about the interaction between the view and the underlying 
> data. I read the Qt docs, but find them quite confusing regarding this 
> matter.
>
> How do I protect and synchronise interaction with the underlying data?
>
> When I populate a TreeNode, eg when I add children to a TreeNode, how do I 
> tell the view to wait and only update when I am done?
>
> *Should I do this in a beginInsertRows() - endInsertRows() block?
>
>  # Get the model index for the parent TreeNode.
>  parentModelIdx = self.createIndex(parent.row(), 0, parent)
>   # childNodes is a list of child TreeNodes.   # insert a new child at end 
> of list of children
>  self.beginInsertRows(parentModelIdx,len(parent.childNodes),len(parent.childNodes))
>
>  # Add the child TreeNode to our underlying data (parent).  
> parent.addChild( child )
>
>  self.endInsertRows() 
>   Should I do this for every node I add?

Depends, if you talk about adding 1 node at a time, then yes. However if
you're going to put this code into a loop to add multiple nodes at once
then move the beginInsertRows and endInsertRows out of that loop and
just change the parameters to beginInsertRows accordingly (i.e.
pre-calculate the number of rows added)

>   Is it acceptable to create the parent model index every time?

Depends on how fast your index-creation is ;) But parent() and index()
are one of the most-called functions in a model anyway, if you have a
bottleneck there you'll notice by simply displaying a pre-generated
tree.

> * OR, should I do something like this:
>  
>  # Tell the view data is going to change:
>
>   self.emit( QtCore.SIGNAL( "layoutAboutToBeChanged()" ) )
>
>  # Change the data by adding a child TreeNode:
>
>   parent.addChild( child )
>
>  # Tell the view we are done.
>
>  self.emit( QtCore.SIGNAL( "layoutChanged()" ) ) 
>
> * OR, should I do both??

Layout changed is a signal that says "hey the order of items changed",
not "hey I've got new items to draw". It might work, but I wouldn't
expect it to work for inserting new items.

> At this stage I am doing something wrong regarding this.  Now and then 
> (sporadically) I get access violations when getting the
> underlying data from a QModelIndex():
>
> tmpTreeNode = currentModelIndex.internalPointer()

I found it better to use internalId() and keep a dict of id->Node items
around. Also makes sure your nodes don't get garbage collected
accidentally.

Andreas

-- 
Your boss is a few sandwiches short of a picnic.


More information about the PyQt mailing list