Erasing items from a canvas

Andrew Dalke dalke at dalkescientific.com
Thu May 23 11:28:25 EDT 2002


Garry Taylor:
>     I am having a little difficulty removing items from a canvas in
>QT/Python, I do a Items = canvas.allItems() and then do a for loop
>which does del(item) on each item, I can then do canvas.allItems()
>again, and get the same number of items

del(item) isn't the right way to do it.  'del' says to remove the
variable definition 'item' from the currently assigned names.
It doesn't say to remove the object to which the name refers.

Consider the following
>>> a = {"city": "Santa Fe"}
>>> b = a
>>> b["state"] = "New Mexico"
>>> a
{'state': 'New Mexico', 'city': 'Santa Fe'}
>>> del b
>>> a
{'state': 'New Mexico', 'city': 'Santa Fe'}
>>> b
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
NameError: b
>>>

This says that first the variable "a" refers to a dictionary
containing the key "city".

Then that variable "b" refers to the same object that "a" refers
to, so that both "a" and "b" refer to the same thing.  This is
very much like how pointers work in C.

They refer to the same object, which is why modifing "b" to have a
"state" also modifies "a".

But "del b" (notice that it's a statement so it doesn't need
the parenthesis) doesn't delete the object, since after all "a"
still refers to it.  The object only gets deleted when there are
no more references to it.  The only thing "del b" does is remove
the name "b" from the list of assigned variables.  So if you try
to ask for it again, you get the NameError exception.


To remove an object from the Qt canvas, in C, you do need to
call "delete item", but Python doesn't support that directly.
Python will delete the object when there are no more references
to the object.

This is made tricky by there being two different types of
references in Qt.  One is a "strong" reference, where Qt keeps
track of Qt objects and deletes an object when the object's
parent no longer needs it.  (Or 'removeChild' is called.)  The
other is a "weak" reference where the reference held by Qt is
not counted as a reference or the purpose of Python's garbage
collection.

(Python has its own concept of weak references.  These two concepts
are similar but are not based on the same code, I believe.)

Items in a canvas are a weak reference, in that you need to keep
explicit references in Python to canvas items.  Once all the Python
references are removed, PyQt calls "delete" on the object, which
then removes it from the canvas.

That means that 'allItems' cannot be used for deletions, as you
supposed.  Instead, you need to have some way to get ahold of all
the original Python object references and remove them.

In my case, my canvas has an attribute called "items" which contains
all of the items in the canvas.  I can remove all the items by
clearing that list.

But I'm also a tyro at Qt and can be wrong about this, so it's
best that you experiment and verify.

                    Andrew
                    dalke at dalkescientific.com






More information about the Python-list mailing list