简短问题:
可以通知处理程序内存泄漏。
长时间的问题:
在C#中,如果我将处理程序附加到事件上
left_object.left_event += right_object.right_handler
然后,当我摆脱right_object
时,我将需要删除处理程序,否则垃圾收集器将永远不会处理它(因为left_object.left_event
保留了指向right_object
的指针)
PyQt信号和时隙也是如此。
left_object.left_signal.connect( right_object.right_handler )
[我从this问题中看到,当调用left_object
或right_object
的析构函数时,Qt自动解除信号和插槽的链接,但是在Python中,我无法显式调用该析构函数,并且right_handler
是普通的-旧功能。
我需要删除处理程序以防止right_object
的内存泄漏,还是PyQt使用某种弱引用?
此设计可能会发生内存泄漏。如果那些连接包含使对象保持活动状态的引用,则需要断开信号和插槽的连接。
是否实际发生取决于right_handler
是什么。如果right_handler
是对self
的引用的闭包,则您有此问题。
但是在Python中,我无法显式调用析构函数,
您可以在python中调用析构函数。检查del和__del__
我是否需要删除处理程序以防止right_objects内存泄漏,
不,您不需要这样做。 python会处理。运行以下代码检查自己。
在此代码中,startButton1
和stopButton1
的信号连接到Hello
的类对象的方法,并且此对象(hello1
)是Widget类的属性。因此,hello1
将一直存在,直到Widget
的生命对象为止,或者我们使用Widget.onDelete
按钮在方法Delete
中将其删除。单击Delete
按钮后,将调用hello1
的析构函数,它将超出范围。现在startButton1
和stopButton1
的信号无法正常工作。
第二行中有startButton2
和stopButton2
按钮,其信号与hello2
的对象相连。但是,一旦Widget
的构造超过hello2
,生命周期就结束了。因此,在Widget
构造结束之后,没有用于这些按钮的信号的插槽连接。
from PyQt5.QtWidgets import QApplication,QPushButton,QWidget,QHBoxLayout,QVBoxLayout
class Hello():
def __init__(self):
print("init")
def onStart(self):
print("onStart");
def onStop(self):
print("onStop");
def __del__(self):
print("del")
class Widget(QWidget):
def __init__(self,parent=None):
QWidget.__init__(self,parent);
vLayout = QVBoxLayout()
self.setLayout(vLayout)
buttons1 = QWidget()
hLayout1 = QHBoxLayout()
buttons1.setLayout(hLayout1)
vLayout.addWidget(buttons1)
startButton1 = QPushButton("Start");
stopButton1 = QPushButton("Stop");
deleteButton1 = QPushButton("Delete");
self.hello1 = Hello();
startButton1.clicked.connect(self.hello1.onStart)
stopButton1.clicked.connect(self.hello1.onStop)
deleteButton1.clicked.connect(self.onDelete)
hLayout1.addWidget(startButton1);
hLayout1.addWidget(stopButton1);
hLayout1.addWidget(deleteButton1);
buttons2 = QWidget()
hLayout2 = QHBoxLayout()
buttons2.setLayout(hLayout2)
vLayout.addWidget(buttons2)
startButton2 = QPushButton("Start");
stopButton2 = QPushButton("Stop");
deleteButton = QPushButton("Delete");
hello2 = Hello();
startButton2.clicked.connect(hello2.onStart)
stopButton2.clicked.connect(hello2.onStop)
hLayout2.addWidget(startButton2);
hLayout2.addWidget(stopButton2);
def onDelete(self):
if hasattr(self,"hello1"):
del self.hello1
app = QApplication([])
w = Widget();
w.show()
app.exec_()
希望这会清除您的疑问。