2013-11-23 2 views

답변

12

"필요한 것"이 무엇을 의미 하느냐에 달려 있습니다.

은 위젯을 닫을 때 (예를 들어)주의를 기울이지 않으면 많은 메모리를 소비 할 수 있습니다. QObject 기반 클래스는 (선택적으로) 계층 구조로 함께 링크되도록 설계되었습니다. 최상위 오브젝트가 삭제되면 Qt는 자동으로 모든 하위 오브젝트도 삭제합니다. 그러나 위젯 (QObject의 하위 클래스)을 닫을 때 자동 삭제는 Qt.WA_DeleteOnClose 속성이 설정된 경우에만 발생합니다 (기본적으로 일반적으로 그렇지 않습니다).

를 열고이 데모 스크립트에서 대화 상자를 닫는 반복 시도, 설명 및 개체의 글로벌리스트가 성장하는 방법 시청하려면 :

PyQt는/PySide와
from PyQt4 import QtCore, QtGui 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     self.checkbox = QtGui.QCheckBox('Delete') 
     self.button = QtGui.QPushButton('Open', self) 
     self.button.clicked.connect(self.openDialog) 
     layout = QtGui.QHBoxLayout(self) 
     layout.addWidget(self.checkbox) 
     layout.addWidget(self.button) 

    def openDialog(self): 
     widget = QtGui.QDialog(self) 
     if (self.checkbox.isChecked() and 
      not widget.testAttribute(QtCore.Qt.WA_DeleteOnClose)): 
      widget.setAttribute(QtCore.Qt.WA_DeleteOnClose) 
      for child in self.findChildren(QtGui.QDialog): 
       if child is not widget: 
        child.deleteLater() 
     label = QtGui.QLabel(widget) 
     button = QtGui.QPushButton('Close', widget) 
     button.clicked.connect(widget.close) 
     layout = QtGui.QVBoxLayout(widget) 
     layout.addWidget(label) 
     layout.addWidget(button) 
     objects = self.findChildren(QtCore.QObject) 
     label.setText('Objects = %d' % len(objects)) 
     print(objects) 
     widget.show() 

if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(500, 300, 100, 50) 
    window.show() 
    sys.exit(app.exec_()) 

, 소유권을 반대하는 두 가지 측면이 다음과 같습니다 파이썬 부분, Qt 부분. 종종 객체에 대한 마지막 파이썬 참조를 제거하는 것만으로는 Qt 측에서 참조가 유지 될 수 있기 때문에 완전히 정리할 수는 없습니다.

일반적으로 Qt는 객체를 암시 적으로 삭제하기 위해 이 아닌입니다. 따라서 응용 프로그램에서 많은 QObject를 만들고 제거하거나 많은 QWidgets를 열거 나 닫으면 일 수 있습니다.은 메모리 사용이 염려되는 경우이를 명시 적으로 삭제해야합니다.

UPDATE :

그냥 위의 오브젝트 소유권에 포인트를 추가 할 수 있습니다. 때로는 객체에 대한 Python 참조를 보유 할 수 있지만 Qt 부분은 삭제됩니다. 이 경우 다음과 같은 오류가 표시됩니다.

RuntimeError: underlying C/C++ object has been deleted

일반적으로 Qt 문서는 이러한 상황이 발생할 수있는시기에 대한 몇 가지 힌트를 제공합니다.

The view does not take ownership of the model unless it is the model's parent object...

이 Qt는 항상 자동으로 reparent하지 않기 때문에 당신이 개체에 파이썬 참조를 유지, 또는 객체의 생성자에 적절한 부모 객체를 전달해야 하나 있음을 말하고있다 : 예를 들어, QAbstractItemView.setModel이 경고를 제공합니다 .

+0

설명해 주셔서 감사합니다. – iMath

+1

1) 나는 PyQt/PySide 또는 Python 부분에 차이가 없다고 생각한다. 객체가 참조되는 한 만큼이나 정리되지 않을 것이다. 그렇게 생각하지 않습니까? 2) 게다가, WA_DeleteOnClose는 닫을 수있는 위젯에 적합하지만 여기 QNetworkReply 및 QDialog와 같은 QOBject에 대해서는 이 닫혀 있지만 삭제되지는 않으며 deleteLater()가 적절합니까? – iMath

+0

@ user1485853 (1) 그렇습니다. 그러나 중요한 예외에 대한 내 답변의 업데이트를보십시오. (2) 예, 'WA_DeleteOnClose'는 _m_ 일들이 제대로 정리되지 않을 때의 일반적인 예입니다.QOjects에 부모가없고 파이썬 참조가 없다면 자동으로 가비지 콜렉션 될 것이므로 결국 deleteLater()가 필요 없다. 일반적으로 명시 적으로 객체를 삭제하는 것에 대해 너무 걱정하지 마십시오. "조숙 한 최적화"에주의하십시오! 문제를 일으키고 있다는 증거가있을 때만이 문제에 대해 걱정하십시오. – ekhumoro

0

deleteLater의 응용 프로그램 중 하나를 사용하면 자신을 정리할 수 있습니다. 즉, 개체 자체 내에서 리소스를 확보하기 위해 QObject 삭제 (예 : 스레딩)를 예약 할 수 있습니다.

여기서 example에 대해 누군가가 신호 thread.finished와 관련하여 그것을 사용하고 있습니다. 그것은 비록 무거운 신호를 가진 경우에만 제한 될 수 있습니다.