19

My PyQt application no longer prints the error (stderr?) to the console.

I use QtDesigner and import the UI like this:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.uic import loadUiType
Ui_MainWindow, QMainWindow = loadUiType("test.ui")

class Main(QMainWindow, Ui_MainWindow):
    """Main window"""
    def __init__(self,parent=None):
        super(Main, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.testfunc)

   def testfunc(self):
        print(9/0)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = Main()
    main.show()
    sys.exit(app.exec_())

test.ui contains a QPushButton and a label. When I call testfunc (which obviously gives an error) in a non-Qt application, I get the error message, traceback, etc. When I execute this code, it just exits.

I wrote a PyQt application without QtDesigner before and it printed the errors to the console as expected. What's the difference with QtDesigner and inheritance?

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Jannis
  • 401
  • 1
  • 4
  • 9
  • Did you install PyQt using the precompiled binary, or did you compiled it yourself? – Daniele Pantaleone Nov 16 '15 at 14:08
  • I used this precombiled 64-bit binary: https://riverbankcomputing.com/software/pyqt/download5 – Jannis Nov 16 '15 at 14:13
  • I guess that is the problem. I had the very same issue, so I reinstalled PyQt5 from sources, compiling it using mingw32 and everything now is working. – Daniele Pantaleone Nov 16 '15 at 14:24
  • I had trouble compiling it so I just rolled back to an earlier version (5.4.1 instead of 5.5.1). This did the trick. The error messages are back and I can properly debug my application. Thank you! – Jannis Nov 16 '15 at 16:10
  • @Jannis How does one roll back to a previous version? Where can those be found? – bkr879 Nov 19 '16 at 14:30
  • @wit221 You probably found these by now: https://sourceforge.net/projects/pyqt/files/PyQt5/ – Jannis Nov 25 '16 at 11:07

2 Answers2

43

This is probably due to changes in the way exceptions are dealt with in PyQt-5.5. To quote from the PyQt5 Docs:

In PyQt v5.5 an unhandled Python exception will result in a call to Qt’s qFatal() function. By default this will call abort() and the application will terminate. Note that an application installed exception hook will still take precedence.

When I run your example in a normal console, this is what I see:

$ python test.py
Traceback (most recent call last):
  File "test.py", line 213, in testfunc
    print(9/0)
ZeroDivisionError: division by zero
Aborted (core dumped)

So the main difference is that the application will now immediately abort when encountering an unhandled exception (i.e. just like a normal python script would). Of course, you can still control this behaviour by using a try/except block or globally by overriding sys.excepthook.

If you're not seeing any traceback, this may be due to an issue with the Python IDE you're using to run your application.

PS:

As a bare minimum, the old PyQt4 behaviour of simply printing the traceback to stdout/stderr can be restored like this:

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

if __name__ == "__main__":

    import sys
    sys.excepthook = except_hook
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Thank you for the response! Yes, when I used a try/except block the application did not terminate. I don't think this is an issue with the IDE. For a non-GUI test I still had the traceback and I tried this with both pycharm and eclipse. And with the older PyQt version the traceback is working as I want it to. With PyQt5.5 could still see the traceback if I ran the program in "debug mode". That was really slow though. How are you supposed to debug a PyQt5.5 application after the latest update? – Jannis Nov 17 '15 at 09:20
  • @Jannis. But that **does** sound like an issue with those IDEs, doesn't it? As I showed in my answer, the traceback *is* shown when I run your script in a console. So why can't your IDEs do that? I have never used an IDE myself, and always set an excepthook in my programs - so nothing much has changed for me when it comes to debugging. – ekhumoro Nov 17 '15 at 15:34
  • You are right, I did not read your comment carefully enough. I reinstalled PyQt5.5 to test this. In a console I get the same output as you. In both pycharm and eclipse the traceback does not show up though. They don't show the traceback with PyQt5.5 while they do show it for PyQt5.4.1. I didn't change any options in between. I will look into using excepthooks soon. For now I am happy with the normal traceback. – Jannis Nov 17 '15 at 16:32
  • Spyder also doesn't show traceback. Is it a correct way to handle this behaviour? https://gist.github.com/Winand/e98e3f2f073826b7c08b58fb6d338b51 – Winand Sep 14 '16 at 06:06
  • @Winand. You should probably ask the Spyder devs. – ekhumoro Sep 14 '16 at 17:23
  • @ekhumoro I have the same issue with Eclipse and Visual Studio Code using PyQT 5.7. Do you happen to know of any IDE which actually shows the error traces? Thank you. – bkr879 Nov 12 '16 at 09:27
  • @wit221. I have never used an IDE myself, so I can't really recommend one. However, [Eric Python IDE](http://eric-ide.python-projects.org/index.html) is itself written in PyQt, so I'd be surprised if it didn't handle tracebacks correctly. – ekhumoro Nov 12 '16 at 16:42
  • Thanks this is perfect, i just added a `sys.exit()` at the end of the function, for it to not keep printing the error – U13-Forward Aug 16 '18 at 08:13
  • [Example](https://stackoverflow.com/a/47275100/2166823) on how to override `sys.excepthook()` – joelostblom Oct 07 '18 at 19:27
0

I've been using python's traceback module in conjunction with a try/except statement to make sure the traceback is printed before exiting: https://docs.python.org/3/library/traceback.html

Spefically, I use traceback.print_exc()