2017-02-08 4 views
1

Почему мое приложение вылетает из строя, когда я запускаю функцию setup_controls() дважды.Pyside сбой при выполнении функции дважды

Я пропустил «родительский/я» где-то, что критично в дизайне?

enter image description here

import sys 
from PySide import QtGui, QtCore 

class QCategoryButton(QtGui.QPushButton): 
    def __init__(self, Text, treeitem, parent=None): 
     super(QCategoryButton, self).__init__(Text, parent) 
     self.treeitem = treeitem 

    def mousePressEvent(self, event): 
     mouse_button = event.button() 
     if mouse_button == QtCore.Qt.LeftButton: 
      self.treeitem.setExpanded(not self.treeitem.isExpanded()) 

class Example(QtGui.QWidget): 

    def __init__(self,): 
     super(Example, self).__init__() 

     self.initUI() 

    def initUI(self): 

     # formatting 
     self.resize(300, 300) 
     self.setWindowTitle("Example") 

     # widgets 
     self.ui_treeWidget = QtGui.QTreeWidget() 
     self.ui_treeWidget.setRootIsDecorated(False) 
     self.ui_treeWidget.setHeaderHidden(True) 
     self.ui_treeWidget.setIndentation(0) 

     self.setup_controls() 
     # self.setup_controls() 

     # layout 
     self.mainLayout = QtGui.QGridLayout(self) 
     self.mainLayout.addWidget(self.ui_treeWidget) 
     self.show()  

    def setup_controls(self): 
     # Add Category 
     pCategory = QtGui.QTreeWidgetItem() 
     self.ui_treeWidget.addTopLevelItem(pCategory) 
     self.ui_toggler = QCategoryButton('Settings', pCategory) 
     self.ui_treeWidget.setItemWidget(pCategory, 0, self.ui_toggler) 

     pFrame = QtGui.QFrame(self.ui_treeWidget) 
     pLayout = QtGui.QVBoxLayout(pFrame) 
     self.ui_ctrl = QtGui.QPushButton('Great') 
     self.ui_ctrlb = QtGui.QPushButton('Cool') 
     pLayout.addWidget(self.ui_ctrl) 
     pLayout.addWidget(self.ui_ctrlb) 

     pContainer = QtGui.QTreeWidgetItem() 
     pContainer.setDisabled(False) 
     pCategory.addChild(pContainer) 
     self.ui_treeWidget.setItemWidget(pContainer, 0, pFrame) 

# Main 
# ------------------------------------------------------------------------------ 
if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 

ответ

1

Метод setItemWidget становится владельцем виджета, который передается ему. Если вы не сохраните ссылку на нее, она может получить сбор мусора на Python. Но, конечно, Qt ничего не знает о Python, поэтому, когда он впоследствии пытается получить доступ к виджету, который больше не существует ... бум!

Это проблематична линия:

self.ui_toggler = QCategoryButton('Settings', pCategory) 

На втором вызове, предыдущий виджет хранится в self.ui_toggler будет удаляется, потому что нет никакой другой ссылки провела для него (на стороне Python). Поэтому вместо этого вы должны это сделать:

ui_toggler = QCategoryButton('Settings', pCategory, self) 
    self.ui_treeWidget.setItemWidget(pCategory, 0, ui_toggler) 
Смежные вопросы