在示例中,当程序运行时,占用了18 MB的RAM。当第二个窗口运行时,RAM将另外占用4 MB。当我们关闭第二个Window时,占用的内存将不会返回到RAM,如果第二次打开第二个Window,则将再次占用4 MB的RAM。您如何解决此问题? 此示例为PyQt4,而我的应用为PyQt5。
此示例来自此链接: PyQT: how to open new window
如果可能,建议使用原理方法打开第二个窗口,并且在关闭后不占用RAM空间的程序。
from PyQt4 import QtGui, QtCore
import sys
class Second(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
class First(QtGui.QMainWindow):
def __init__(self, parent=None):
super(First, self).__init__(parent)
self.pushButton = QtGui.QPushButton("click me")
self.setCentralWidget(self.pushButton)
self.pushButton.clicked.connect(self.on_pushButton_clicked)
self.dialogs = list()
def on_pushButton_clicked(self):
dialog = Second(self)
self.dialogs.append(dialog)
dialog.show()
def main():
app = QtGui.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
PyQt5中的示例
from PyQt5 import QtCore, QtGui, QtWidgets, uic
import sys
class Second(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
class First(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(First, self).__init__(parent)
self.pushButton = QtWidgets.QPushButton("click me")
self.setCentralWidget(self.pushButton)
self.pushButton.clicked.connect(self.on_pushButton_clicked)
self.dialogs = list()
def on_pushButton_clicked(self):
dialog = Second(self)
self.dialogs.append(dialog)
dialog.show()
def main():
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:3)
在PyQt中,取决于您配置对象的方式,可以使用C ++或Python管理属性。对于QObject(例如QMainWindow)如果传递了父对象,则内存处理为C ++,并且Qt规则指示仅当父对象去世或使用deleteLater明确删除子对象时,子对象才会死亡。因此,Second的生命周期取决于First,也就是说,即使关闭窗口,该对象也不会被删除。对于要在关闭窗口时删除的窗口,必须激活属性Qt::WA_DeleteOnClose,因此解决方案是将其添加到Second类中:
class Second(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Second, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) # <---
如果要使用容器保存对象的引用,则可能会遇到问题,因为C ++删除对象时不会通知容器。因此,有以下几种选择可以避免这些问题:
def on_pushButton_clicked(self):
dialog = Second(self)
self.dialogs.append(weakref.ref(dialog, self.dialogs.remove))
dialog.show()
import sip
# ...
class First(QtWidgets.QMainWindow):
# ...
def on_pushButton_clicked(self):
dialog = Second(self)
dialog.destroyed.connect(self.on_destroyed)
self.dialogs.append(dialog)
dialog.show()
@QtCore.pyqtSlot('QObject*')
def on_destroyed(self, obj):
self.dialogs = [dialog for dialog in self.dialogs if not sip.isdeleted(dialog)]