JPF*_*oia 5 python memory pyqt
假设我想创建一个对话框,我的主程序的子代:
from PyQt4 import QtGui, QtCore
class WizardJournal(QtGui.QDialog):
def __init__(self, parent):
super(WizardJournal, self).__init__(parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.wizard = QtGui.QWidget()
self.ok_button = QtGui.QPushButton("OK", self)
self.vbox_global = QtGui.QVBoxLayout(self)
self.vbox_global.addWidget(self.ok_button)
self.paret.wizard.setLayout(self.vbox_global)
self.parent.wizard.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
parent = QtGui.QWidget()
obj = WizardJournal(parent)
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
该对话框将由我的主程序打开和关闭.有关内存消耗的更好方法:
self.ok_button = QtGui.QPushButton("OK", self)self.ok_button = QtGui.QPushButton("OK")基本上,我想知道在创建窗口小部件时是否应该提到父窗口小部件.当我关闭此对话框时,如果在创建父窗口小部件时没有提及父窗口小部件,是否会从内存中释放确定按钮?
ekh*_*oro 14
鉴于您的示例当前的结构方式,对话框及其任何子窗口小部件在关闭时都不会被删除.
您可以通过将示例的结尾更改为如下所示来查看:
app.exec_()
print('\n'.join(repr(w) for w in app.allWidgets()))
Run Code Online (Sandbox Code Playgroud)
这将给出这样的输出(一旦对话框关闭):
<__main__.WizardJournal object at 0x7fcd850f65e8>
<PyQt4.QtGui.QPushButton object at 0x7fcd850f6708>
<PyQt4.QtGui.QWidget object at 0x7fcd850f6558>
<PyQt4.QtGui.QDesktopWidget object at 0x7fcd850f6828>
<PyQt4.QtGui.QWidget object at 0x7fcd850f6678>
Run Code Online (Sandbox Code Playgroud)
在PyQt中,你必须要知道对象可能有两种引用:一种是Python端(PyQt包装器对象),另一种是C++端(底层Qt对象).因此,要完全删除对象,您需要删除所有这些引用.
通常,Qt不会删除对象,除非您明确告诉它这样做.在使用父对象创建对话框时,您需要注意这一点,否则很容易产生内存泄漏.看到这样编写的代码很常见:
def openDialog(self):
dialog = MyDialog(self)
dialog.show()
Run Code Online (Sandbox Code Playgroud)
乍一看看起来很无害 - 但是每次调用它时该方法都会创建一个新的对话框,Qt最终将继续保持它们中的每一个(因为parentC++方面的引用).避免这种情况的一种方法是重新编写方法,以便它只在Python端保留引用:
def openDialog(self):
self.dialog = MyDialog()
self.dialog.show()
Run Code Online (Sandbox Code Playgroud)
但是如何处理必须拥有父级的模态对话框呢?在这种情况下,您可以像这样初始化对话框类:
class MyDialog(QtGui.QDialog):
def __init__(self, parent):
super(MyDialog, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
Run Code Online (Sandbox Code Playgroud)
现在,Qt会在关闭时自动删除对话框,并且还会递归删除所有子对象.这将留下一个空的PyQt包装器对象,它最终会被Python垃圾收集器删除.
所以对于你的特定例子,我想我会重新编写它看起来像这样:
import sys
from PyQt4 import QtGui, QtCore
class WizardJournal(QtGui.QDialog):
def __init__(self, parent):
super(WizardJournal, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.initUI()
def initUI(self):
self.ok_button = QtGui.QPushButton("OK", self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.ok_button)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
parent = QtGui.QWidget()
obj = WizardJournal(parent)
app.exec_()
print('\n'.join(repr(w) for w in app.allWidgets()))
Run Code Online (Sandbox Code Playgroud)
对话框类现在完全是自包含的,并且只有一个外部python引用它的实例.(如果需要从对话框类中访问父窗口小部件,则可以使用self.parent()).
PS:当小部件被添加到布局时,它们将自动重新设置为任何顶级小部件最终包含布局的父级.因此,严格来说,没有必要在代码中为这些小部件显式设置父级.
| 归档时间: |
|
| 查看次数: |
7416 次 |
| 最近记录: |