简体   繁体   中英

PyQt5 app exits on error where PyQt4 app would not

I have been developing a scientific application using PyQt4 for a couple of weeks, and decided to switch over to PyQt5. Aside from a few things to iron out one thing is puzzling me, and I'm not sure if its intended behavior or not.

When Using PyQt4: if I had a python error (AttributeError, FileNotFoundError or whatever) the error message would print out to the python console, but I could continue using the PyQt4 gui application

When Using PyQt5, when I have a python error, the entire app closes on me. Is this a setting, or is this intended behavior? This is potentially disastrous as before if there was a bug, I could save the data I had acquired, but now the application will just close without warning.

Here is an example that demonstrates the behavior. This script opens a widget with a button that activates a file dialog. If a valid file is selected, the code will print the filepointer object to the command line. If no file is selected because the user hits cancel, then that case is not handled and python tries to open a file with path ''. In this both PyQt4 and PyQt5 versions throw the same python error:

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

However, the PyQt4 version will leave the widget open and the user can continue, whereas the PyQt5 version closes, with exit code of 1.

Here is the example code, executed by: "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_())

Can I use PyQt5, but have it not crash the way that the PyQt4 version does?

Here is my current system information system information:
Windows 7 64-bit
Anaconda, Python 3.5
PyQt4 --> from conda sources
PyQt5 --> using:

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

both PyQt4 and PyQt5 are installed side by side

The old behavior can be forced by calling this code, which I found after more searching. I'm not sure I understand why this is bad behavior that needed to be deprecated, but this does work.

I submit that this should not be the default behavior, and that properly catching exceptions is the correct way to program, but given the specific purpose of my programming, and my time constraints, I find it useful to have access to as an optional mode, as I can still see the python exception traces printed to the console, and won't lose any unsaved data because of an uncaught exception.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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