0

I am trying to find out how to delete a QGraphicsItem using python. Currently, I am using scene.removeItem(item) to remove the item from a QGraphicsScene. However, does that delete the item as well (from memory)?

If not, is there a way to do so? Will the del keyword accomplish this? Sorry, I'm fairly new to this so I would appreciate any advice/feedback.

spaL
  • 604
  • 7
  • 21

2 Answers2

3

When adding an item to the scene the one that manages the memory of the item is no longer python but the scene but when you use removeItem() does not remove it from memory but returns ownership of the item to python, and in that case python remove it when deemed necessary, to verify I have created a simple example:

from PyQt5 import QtCore, QtWidgets


class GraphicsRectItem(QtWidgets.QGraphicsRectItem):
    def __del__(self):
        print("deleted")


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        self.scene = QtWidgets.QGraphicsScene()
        self.view = QtWidgets.QGraphicsView(self.scene)
        self.setCentralWidget(self.view)

        item = GraphicsRectItem(10, 10, 100, 100)
        self.scene.addItem(item)

        QtCore.QTimer.singleShot(1000, lambda: self.scene.removeItem(item))


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)

    mytable = MainWindow()
    mytable.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

If you want to explicitly remove from memory the C++ object (not the python object) then you can use sip:

from PyQt5.QtWidgets import QGraphicsScene
# sip should be imported after pyqt5
import sip
# ...
scene.removeItem(item)
sip.delete(item)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
0

In python there is an Entity that is called the GarbageCollector (GC) which takes care of "storing" the deleted objects every object, you can read more in the docs for details.

The values of your program’s objects are stored in memory for quick access. In many programming languages, a variable in your program code is simply a pointer to the address of the object in memory. When a variable is used in a program, the process will read the value from memory and operate on it. In early programming languages, developers were responsible for all memory management in their programs. This meant before creating a list or an object, you first needed to allocate the memory for your variable. After you were done with your variable, you then needed to deallocate it to “free” that memory for other users. Python's garbage collector is an automatic memory allocator, removing the need to do it yourself.

Using the __del__ property of an object will only detach the variable's name to the object itself, but the object won't actually be flushed from the memory, it will be caught by the garbage collector, which will allow the object to be flushed if the GC find it's necessary.

To flush the garbage collector, you can use python's gc module. the collect() method flushes the memory of the garbage collector.

import gc
gc.collect()

view this thread for more info on garbage collection.

PyThagoras
  • 195
  • 2
  • 18