簡體   English   中英

關閉第二個窗口后如何清空 RAM?

[英]How to empty the RAM after closing the second Window?

在示例中,當程序運行時,占用了 18 MB 的 RAM。 當第二個 Window 運行時,另外 4 MB 將被 RAM 占用。 當我們關閉第二個 Window 時,占用的內存不會歸還到 RAM 中,如果第二次打開第二個 Window ,則會再次占用 4 MB 的 RAM。 你對這個問題的解決方案是什么? 這個例子是 PyQt4 而我的應用程序是 PyQt5。

這個例子來自這個鏈接: PyQT:如何打開新窗口

如果可能的話,提出一個程序,用原理方法打開第二個窗口,關閉后不占用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()

在 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++ 刪除對象時,它不會通知容器。 因此,有以下選項可以避免這些問題:

  • 不要使用容器。
  • 使用weakref.ref()這樣當對象被刪除時,它也會從容器中刪除:
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)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM