[PyQt] model/view/delegate: keep the index of the item during edition with a QSpinBox

TP paratribulations at free.fr
Mon Mar 16 22:12:44 GMT 2009


Hi everybody,

I have adapted the tree example using model/view/delegate proposed in the
book of Summerfield (p.492-504): I obtain a custom tree widget.
In my custom tree widget, I want to be able to add children by setting the
number of children of a parent; this is done with a delegate using a
QSpinBox. My problem is to change the tree dynamically when I increment or
decrement the integer displayed in the QSpinBox.

To do this, my problem is to know which node of my underlying tree data
structure corresponds to the edited item. For this, I need the index of the
item (so as to use index.internalPointer() ).

I have simplified my widget a lot to focus on my problem:

http://paratribulations.free.fr/help/python/integerdelegate_question.py

If you run this script, you obtain a QTreeView with 2 rows and 2 columns.
Double-click on the upper right cell (containing "1"), increment the
QSpinBox to obtain 2, and decrement to obtain 1 again. Then click in any
other cell so as to leave the QSpinBox. Then kill (or leave) the
application.
On the standard output, you should have obtained:

####
integer delegate creation at row=0 and col=1
delegate creation at ( 0, 1 )
index (create editor original)= <PyQt4.QtCore.QModelIndex object at
0xb7cfcdac> (column=1, row=0)
index (set data)= <PyQt4.QtCore.QModelIndex object at 0xb7cfcdac>
(column=135977084, row=7)
add line 2
inform view!
index (set data)= <PyQt4.QtCore.QModelIndex object at 0xb7cfcdac>
(column=-1227142752, row=-1209294484)
remove line 3
inform view!
index (set data)= <PyQt4.QtCore.QModelIndex object at 0xb7cfcd6c> (column=1,
row=0)
####

The heart of the problem lies in the following methods:

* method "createEditor" of class "IntegerDelegate"
* method "setData" of class "TreeRWModel"

When you have incremented and decremented the QSpinBox, the tree was updated
automatically, while the QSpinBox was still "opened". This is due to the
function "liveSetData" in "createEditor". The key instructions are:

model = parent.parent().model()
model.informView()

It works perfectly: the view is informed, and updates its structure
dynamically: the view corresponds perfectly to the model.
Here I do not need the index of the clicked item in the setData method,
because my data structure is very simple.
But in my real application, I need the index. Unfortunately it does not
work: the index given to setData by "liveSetData" gives dummy values of
column and row (for example, column=135977084, see above). I think the
reason is that the underlying C/C++ object has been deleted. I haven't
found any way to keep a reference to the index so that it is not deleted. I
have tried to use deepcopy too.

How to keep a clean index and give it to the setData method?

Thanks

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)



More information about the PyQt mailing list