PyQt5 应用程序在 PyQt4 应用程序不会出现错误时退出

PyQt5 app exits on error where PyQt4 app would not

几周来我一直在使用 PyQt4 开发科学应用程序,并决定切换到 PyQt5。除了一些需要解决的问题外,有一件事让我感到困惑,我不确定它是否是预期的行为。

使用 PyQt4 时: 如果我遇到 python 错误(AttributeError、FileNotFoundError 或其他),错误消息将打印到 python 控制台,但我可以继续使用 PyQt4 gui 应用程序

使用 PyQt5 时,当我遇到 python 错误时,整个应用程序都会关闭。这是一种设置,还是这种预期的行为?如果有错误,这可能是灾难性的,因为我可以保存我获得的数据,但现在应用程序将在没有警告的情况下关闭。

这是一个演示该行为的示例。此脚本打开一个带有激活文件对话框的按钮的小部件。如果选择了有效文件,代码会将文件指针对象打印到命令行。如果因为用户点击取消而没有选择文件,则不会处理这种情况,并且 python 会尝试打开路径为 '' 的文件。在此 PyQt4 和 PyQt5 版本都抛出相同的 python 错误:

FileNotFoundError: [Errno 2] No such file or directory: ''

但是,PyQt4 版本将使小部件保持打开状态,用户可以继续,而 PyQt5 版本将关闭,退出代码为 1。

这是示例代码,执行者:"python script.py"

import sys
# from PyQt4 import QtGui as qt
# from PyQt4.QtCore import PYQT_VERSION_STR
from PyQt5 import QtWidgets as qt
from PyQt5.QtCore import PYQT_VERSION_STR

def open_a_file():
    fname = qt.QFileDialog.getOpenFileName()
    if PYQT_VERSION_STR[0] == '4':
        f = open(fname, 'r')
        print(f)
    else:
        f = open(fname[0], 'r')
        print(f)
    f.close()

if __name__ == '__main__':
    app = qt.QApplication(sys.argv)

    w = qt.QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('PyQt 4 v 5')
    btn = qt.QPushButton("Open a file", w)
    btn.clicked.connect(open_a_file)
    w.show()

    sys.exit(app.exec_())

我可以使用 PyQt5,但不会像 PyQt4 版本那样崩溃吗?

这里是我当前的系统信息系统信息:
Windows 7 个 64 位
蟒蛇,Python 3.5
PyQt4 --> 来自 conda 来源
PyQt5 --> 使用:

conda install --channel https://conda.anaconda.org/m-labs qt5
conda install --channel https://conda.anaconda.org/m-labs pyqt5

PyQt4 和 PyQt5 并排安装

旧的行为可以通过调用这段代码来强制执行,这是我在更多搜索后发现的。 我不确定我是否理解为什么这是需要弃用的不良行为,但这确实有效。

我认为这不应该是默认行为,正确捕获异常是正确的编程方式,但考虑到我编程的特定目的和我的时间限制,我发现访问作为可选模式,因为我仍然可以看到打印到控制台的 python 异常跟踪,并且不会因为未捕获的异常而丢失任何未保存的数据。

import sys

def my_excepthook(type, value, tback):
    # log the exception here

    # then call the default handler
    sys.__excepthook__(type, value, tback)

sys.excepthook = my_excepthook