繁体   English   中英

清除QTreeWidget时,PyQt5 GUI崩溃

[英]PyQt5 GUI crashes when QTreeWidget is cleared

当#从下面的代码中的行中删除时,为什么在单击按钮时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_())

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

回答具体问题:为什么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

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

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

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

如果树中没有任何内容, self.treeWidget.currentItem()将返回None current_selectionitemNone ,这就是你得到的原因:

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)
    ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM