如何删除 Pyqt5 中的 QGraphicsItem
How to delete a QGraphicsItem in Pyqt5
我正在尝试了解如何使用 python 删除 QGraphicsItem。目前,我正在使用 scene.removeItem(item)
从 QGraphicsScene 中删除项目。但是,这是否也删除了该项目(从内存中)?
如果不行,有什么办法吗? del
关键字能做到这一点吗?
抱歉,我对此很陌生,所以我将不胜感激 advice/feedback.
在 python 中有一个名为 GarbageCollector (GC) 的实体,它负责“存储”每个对象的已删除对象,您可以在 docs 中阅读更多详细信息。
程序对象的值存储在内存中以便快速访问。在许多编程语言中,程序代码中的变量只是指向内存中对象地址的指针。当在程序中使用变量时,进程将从内存中读取值并对其进行操作。在早期的编程语言中,开发人员负责他们程序中的所有内存管理。这意味着在创建列表或对象之前,您首先需要为变量分配内存。处理完变量后,您需要释放它以便为其他用户“释放”该内存。 Python 的垃圾收集器是一个自动内存分配器,无需您自己动手。
使用对象的__del__
属性只会将变量名分离到对象本身,但对象实际上不会从内存中刷新,它会被垃圾收集器,如果 GC 发现有必要,它将允许刷新对象。
要刷新垃圾收集器,您可以使用 python 的 gc
模块。 collect()
方法刷新垃圾收集器的内存。
import gc
gc.collect()
查看此 thread 了解有关垃圾收集的更多信息。
将项目添加到场景时,管理项目内存的不再是 python,而是场景,但是当您使用 removeItem()
时,不会将其从内存中删除,而是 returns 将项目的所有权授予 python,在这种情况下 python 在认为必要时将其删除,以验证我创建了一个简单的示例:
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()
如果你想明确地从内存中删除 C++ 对象(而不是 python 对象),那么你可以使用 sip:
from PyQt5.QtWidgets import QGraphicsScene
# sip should be imported after pyqt5
import sip
# ...
scene.removeItem(item)
sip.delete(item)
我正在尝试了解如何使用 python 删除 QGraphicsItem。目前,我正在使用 scene.removeItem(item)
从 QGraphicsScene 中删除项目。但是,这是否也删除了该项目(从内存中)?
如果不行,有什么办法吗? del
关键字能做到这一点吗?
抱歉,我对此很陌生,所以我将不胜感激 advice/feedback.
在 python 中有一个名为 GarbageCollector (GC) 的实体,它负责“存储”每个对象的已删除对象,您可以在 docs 中阅读更多详细信息。
程序对象的值存储在内存中以便快速访问。在许多编程语言中,程序代码中的变量只是指向内存中对象地址的指针。当在程序中使用变量时,进程将从内存中读取值并对其进行操作。在早期的编程语言中,开发人员负责他们程序中的所有内存管理。这意味着在创建列表或对象之前,您首先需要为变量分配内存。处理完变量后,您需要释放它以便为其他用户“释放”该内存。 Python 的垃圾收集器是一个自动内存分配器,无需您自己动手。
使用对象的__del__
属性只会将变量名分离到对象本身,但对象实际上不会从内存中刷新,它会被垃圾收集器,如果 GC 发现有必要,它将允许刷新对象。
要刷新垃圾收集器,您可以使用 python 的 gc
模块。 collect()
方法刷新垃圾收集器的内存。
import gc
gc.collect()
查看此 thread 了解有关垃圾收集的更多信息。
将项目添加到场景时,管理项目内存的不再是 python,而是场景,但是当您使用 removeItem()
时,不会将其从内存中删除,而是 returns 将项目的所有权授予 python,在这种情况下 python 在认为必要时将其删除,以验证我创建了一个简单的示例:
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()
如果你想明确地从内存中删除 C++ 对象(而不是 python 对象),那么你可以使用 sip:
from PyQt5.QtWidgets import QGraphicsScene
# sip should be imported after pyqt5
import sip
# ...
scene.removeItem(item)
sip.delete(item)