清除QTreeWidget时,PyQt5 GUI崩溃

时间:2016-02-24 07:53:25

标签: python pyqt5

当从下面的代码中的行中删除#时,为什么单击按钮时GUI会崩溃?

代码中的行是:

  

self.treeWidget.currentItemChanged.connect(self.current_selection)

from PyQt5 import QtWidgets

class Ui_Form(object):

    def setupUi(self, Form):

        Form.setWindowTitle("Test")
        Form.resize(600, 400)

        self.gridLayout = QtWidgets.QGridLayout(Form)

        self.treeWidget = QtWidgets.QTreeWidget(Form)
        self.treeWidget.setColumnCount(3)
        self.treeWidget.setHeaderLabels(['No.', 'Colour', 'Animal'])
        #self.treeWidget.currentItemChanged.connect(self.current_selection)

        self.buttonWidget1 = QtWidgets.QPushButton('Click1')
        self.buttonWidget1.clicked.connect(self.test1)

        self.gridLayout.addWidget(self.treeWidget, 0, 0)
        self.gridLayout.addWidget(self.buttonWidget1, 1, 0)

        self.populate()

    def test1(self):
        self.treeWidget.clear()

    def current_selection(self):
        item = self.treeWidget.currentItem()
        self.no = item.text(0)
        self.colour = item.text(1)
        self.animal = item.text(2)
        print(self.no, self.colour, self.animal)

    def populate(self):
        item = QtWidgets.QTreeWidgetItem(['1', 'Yellow', 'Dog'])
        self.treeWidget.addTopLevelItem(item)

        item = QtWidgets.QTreeWidgetItem(['2', 'Black', 'Cat'])
        self.treeWidget.addTopLevelItem(item)

        item = QtWidgets.QTreeWidgetItem(['3', 'Green', 'Frog'])
        self.treeWidget.addTopLevelItem(item)

        item = QtWidgets.QTreeWidgetItem(['4', 'Blue', 'Snail'])
        self.treeWidget.addTopLevelItem(item)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

如果有人能向我解释发生了什么,我们将非常感激。

2 个答案:

答案 0 :(得分:2)

回答具体问题:为什么GUI 崩溃

这是由于PyQt-5.5引入的新行为。引用PyQt5文档:

  

在PyQt v5.5中,未处理的Python异常将导致调用   Qt的qFatal()函数。默认情况下,这将调用abort()和   申请将终止。请注意,已安装应用程序   异常钩子仍然优先。

幸运的是,正如最后一句所示,可以通过安装excepthook来绕过这种新行为,这将允许您的程序以更优雅的方式处理未处理的异常。

作为最低限度,简单地将回溯打印到stdout / stderr的旧行为可以像这样恢复:

def except_hook(cls, exception, traceback):
    sys.__excepthook__(cls, exception, traceback)

if __name__ == "__main__":

    import sys
    sys.excepthook = except_hook

但显然,在某种消息框中显示错误将是一种更为可取的方式来通知用户发生了问题。

答案 1 :(得分:1)

默认情况下,如果没有选择,currentItem()是树中的第一个项目。

单击该按钮时,将调用self.treeWidget.clear()。所有项目都从树窗口小部件中删除,因此不再有第一个项目:发出信号currentItemChanged

如果树中没有任何内容,self.treeWidget.currentItem()将返回None。在current_selection中,itemNone,这就是您获得的原因:

  

AttributeError:'NoneType'对象没有属性'text'

要解决此问题,您可以先测试item是否为None,然后再继续:

def current_selection(self):
    item = self.treeWidget.currentItem()
    if item is not None:
        self.no = item.text(0)
        self.colour = item.text(1)
        self.animal = item.text(2)
    ...
相关问题