이미 파이썬에 가비지 컬렉터가 있으므로 PyQt/PySide에서 deleteLater()가 필요합니까?PyQt/PySide에서 deleteLater()가 필요합니까?
답변
"필요한 것"이 무엇을 의미 하느냐에 달려 있습니다.
은 위젯을 닫을 때 (예를 들어)주의를 기울이지 않으면 많은 메모리를 소비 할 수 있습니다. 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이 경고를 제공합니다 .
deleteLater
의 응용 프로그램 중 하나를 사용하면 자신을 정리할 수 있습니다. 즉, 개체 자체 내에서 리소스를 확보하기 위해 QObject 삭제 (예 : 스레딩)를 예약 할 수 있습니다.
여기서 example에 대해 누군가가 신호 thread.finished와 관련하여 그것을 사용하고 있습니다. 그것은 비록 무거운 신호를 가진 경우에만 제한 될 수 있습니다.
- 1. 왜 QByteArray에 deleteLater가 없습니까?
- 2. 필요합니까?
- 3. 필요합니까? 아니면 그냥 저장소가 필요합니까?
- 4. 이 계약을 증명하기 위해서는 무엇이 필요합니까? 필요합니까?
- 5. 장고에는 IDE가 필요합니까? ASP.NET에는 Visual Studio가 필요합니까?
- 6. Zend_Acl이 필요합니까?
- 7. UINavigationController가 필요합니까?
- 8. 동기화가 필요합니까?
- 9. lockbits가 필요합니까?
- 10. main.cpp가 필요합니까?
- 11. os.path.join이 필요합니까?
- 12. UINavigationController가 필요합니까?
- 13. LDT가 필요합니까?
- 14. backbone.js가 필요합니까?
- 15. SQLiteCommand.Transaction이 필요합니까?
- 16. 무엇이 필요합니까 ('../')?
- 17. 휘발성이 필요합니까?
- 18. 프로필이 필요합니까?
- 19. app.config가 필요합니까?
- 20. UIPrerenderedIcon이 필요합니까?
- 21. 포인터가 필요합니까?
- 22. 쿠키가 필요합니까?
- 23. my_require_once가 필요합니까?
- 24. DefaultAppPool이 필요합니까?
- 25. 신고서가 필요합니까?
- 26. $ .when.apply가 필요합니까?
- 27. 가상화가 필요합니까?
- 28. 컬렉션이 필요합니까?
- 29. 파티셔너가 필요합니까?
- 30. glDisableClientState가 필요합니까?
설명해 주셔서 감사합니다. – iMath
1) 나는 PyQt/PySide 또는 Python 부분에 차이가 없다고 생각한다. 객체가 참조되는 한 만큼이나 정리되지 않을 것이다. 그렇게 생각하지 않습니까? 2) 게다가, WA_DeleteOnClose는 닫을 수있는 위젯에 적합하지만 여기 QNetworkReply 및 QDialog와 같은 QOBject에 대해서는 이 닫혀 있지만 삭제되지는 않으며 deleteLater()가 적절합니까? – iMath
@ user1485853 (1) 그렇습니다. 그러나 중요한 예외에 대한 내 답변의 업데이트를보십시오. (2) 예, 'WA_DeleteOnClose'는 _m_ 일들이 제대로 정리되지 않을 때의 일반적인 예입니다.QOjects에 부모가없고 파이썬 참조가 없다면 자동으로 가비지 콜렉션 될 것이므로 결국 deleteLater()가 필요 없다. 일반적으로 명시 적으로 객체를 삭제하는 것에 대해 너무 걱정하지 마십시오. "조숙 한 최적화"에주의하십시오! 문제를 일으키고 있다는 증거가있을 때만이 문제에 대해 걱정하십시오. – ekhumoro