2012-12-11 4 views
6

PyQt4를 사용할 때 위젯을 정리/삭제하는 '올바른'또는 관용적 인 방법은 무엇입니까?pyqt에서 위젯을 정리하는 올바른 방법

다음 코드를 고려하십시오

choices = ['a', 'b', 'c'] 
checkboxes = [] 
layout = QtGui.QVBoxLayout() 

dialog = MyDialog() 

for c in choices: 
    checkboxes.append(QtGui.QCheckBox(c) 
    layout.addWidget(chkbox) 

dialog.setLayout(layout) 

for c in checkboxes: 
    c.setParent(None) 
    c.deleteLater() 
    c = None 

위의 코드는, deleteLater()setParent() 사용하고 None에 개체를 설정. 이 모든 것이 필요한가요?

또 다른 가능한 시나리오는 위젯이있는 대화 상자가 있고이 위젯을 제거하고 새 위젯을 추가하려고합니다. 이전 위젯을 '누출'하고 싶지는 않지만 이런 식으로 올바른 방법이 무엇인지 확신 할 수 없습니다.

deleteLater()은 절대로 필요하지 않을 수도 있습니다. 그것은 단지 참조 횟수를 감소 시키는가? 그렇다면 변수를 None으로 설정하는 것이 똑같은 일을하지 않을까요?

답변

15

꼭 기억해야 할 것은 위젯에 부모/자식 관계를 사용하는 것입니다. 이 작업을 수행하면 Qt가 소유하게되며 부모가 삭제되면 모든 하위 항목이 자동으로 정리됩니다.

dialog = MyDialog() 

for c in choices: 
    checkboxes.append(QtGui.QCheckBox(c, parent=dialog)) 
    layout.addWidget(chkbox) 

이 경우 대화 상자를 삭제할 때 모든 확인란이 올바르게 정리됩니다. 이것은 질문의 한 부분을 처리합니다. 레이아웃에 추가 할 때 암시 적으로 부모가 설정되어 있음을 알게됩니다. 그러나 삭제하기 전에 부모를 삭제해서는 안됩니다. 은 자식을 자동으로 제거 할 수있는 부모 관계 인입니다. 참조 횟수가 아닙니다. 참조 측면은 더 이상 참조가 없을 때 가비지 수집 될 파이썬 쪽 일 것입니다.

deleteLater은 제어가 이벤트 루프로 반환 될 때 삭제가 발생하도록하려면 매우 중요합니다. 이 방법이 완료되면이 위젯은 실제로 삭제됩니다

# clear a layout and delete all widgets 
# aLayout is some QLayout for instance 
while aLayout.count(): 
    item = aLayout.takeAt(0) 
    item.widget().deleteLater() 

: 그것은 또한 당신이 레이아웃에서 일부를 제거하고 새로운 것을 추가하는 위젯을 삭제하는 안전한 방법입니다. deleteLater은 슬롯이나 이벤트가 현재 발생하고있는 위젯을 삭제할 때도 유용합니다. 클릭시 자체를 삭제할 수있는 QPushButton 등.

c = None도 설정할 필요가 거의 없습니다. 일단 부모가 삭제되고, 모든 자식의 삭제를 재귀 적으로 트리거하면, 그 객체에 대한 파이썬 참조는 무효가됩니다. 따라서 이제는 더 이상 사용하지 않아야합니다. 목록에있는 경우 목록을 지 웁니다. 액세스하면 RuntimeError: wrapped C/C++ object of %S has been deleted이 삭제된다는 의미입니다.

+0

레이아웃에 추가 할 모든 객체를 만들 때'parent' 인수를 사용해야합니까? 아마 이것이 좀 더 명백한 것임을 알았지 만 필요합니까? –

+0

아니요. 그것들을 레이아웃에 직접 추가하는 경우, 레이아웃은 레이아웃의 소유자의 자식이됩니다. – jdi

+0

파티에 매우 늦었지만, 추가 할 것이라고 생각했습니다. - 'parent'인수를 사용하는 것은 불필요하지만, 코드의 구조를 조금 제한하고 다른 사람들이 쉽게 사용할 수 있기 때문에 아마 좋은 생각 일 것입니다 의도 한 봉쇄 계급이 무엇인지 확인하십시오. – Emmet

관련 문제