Reputation: 153
Spyder 3.3.2 Python 2.7.15 64-bit | Qt 5.6.2 | PyQt5 5.6 | Windows 10 iPython
The following code was working yesterday, opening a file dialog and allowing me to select a file. It has stopped working, I don't get any dialog at all.
from PyQt5.QtWidgets import QFileDialog # note this is correct code as I use it
filename=QFileDialog.getOpenFileName(None,"Open Data File",'.',"*.xlsx)")
print filename
Other simple examples using PyQt5 that worked yesterday no longer do so. I have tried various things to resolve this, but have not gotten anywhere. I have rebooted, reset Spyder, updated conda, run in debug, etc. At a loss here. By no means a python expert.
Here is the console log, note that if I just execute the import statement by itself, then I see QFileDialog in the dir(). If I execute all 3 lines, QFileDialog does not appear. Nothing happens if I execute QFileDialog in console window.
> %reset
>
> Once deleted, variables cannot be recovered. Proceed (y/[n])? y
>
> dir() Out[3]: ['In', 'Out', '__builtin__', '__builtins__',
> '__name__', '_dh', '_i', '_i3', '_ih', '_ii', '_iii', '_oh',
> '_sh', 'exit', 'get_ipython', 'quit']
>
> runfile('C:/Projects/GenIICoastalModel/Python/NonCHS/NonCHS/TestReadFile.py',
> wdir='C:/Projects/GenIICoastalModel/Python/NonCHS/NonCHS')
>
> dir() Out[1]: ['In', 'Out', '_', '__', '___', '__builtin__',
> '__builtins__', '__doc__', '__name__', '__package__', '_dh',
> '_i', '_i1', '_ih', '_ii', '_iii', '_oh', '_sh', 'exit',
> 'get_ipython', 'quit']
>
> '
Upvotes: 0
Views: 404
Reputation: 8634
I don't know why your code is behaving differently now than it did in the past. But the reason why PyQt code can crash without displaying any python error traceback is succinctly explained here. To quote:
The first thing to understand about pyqt is that it is simply a wrapper around the Qt C++ library, so nearly everything pyqt related in your application is executed as a C++ wrapper (loose definition).
Secondly, understand that pyqt is event driven, and therefore has it's own event loop that runs throughout the execution of your script, that (as i understand it) runs in it's own thread of execution.
Because of this, any errors or exceptions that are raised inside a slot triggered by a qt signal/event (button click, key press, etc) will be processed by the qt event loop in c++ land, and because of this, any exceptions raised in said slot will essentially be out of scope of the python interpreter, and therefore not raised outside of the scope of the slot. So in essence, while an exception may be raised in the context of a qt slot, once it leaves the scope of that slot, the exception is essentially erased.
I experience a crash without any error information as well when I execute your example code in Spyder. However when I execute your example code in an IPython console inside Windows Command Prompt then the following short error message is displayed:
QWidget: Must construct a QApplication before a QWidget
So apparently the issue was that no QApplication
object was explicitly constructed. Give this a try:
from __future__ import print_function # not needed in python 3
from PyQt5 import QtWidgets
class FileDialog(QtWidgets.QFileDialog):
def __init__(self, parent=None):
super(FileDialog, self).__init__(parent) # can be simplified to `super().__init__(parent)` in python 3
self.fileSelected.connect(lambda x: print(x))
def run_app():
app = QtWidgets.QApplication([])
file_dialog = FileDialog()
file_dialog.show()
app.exec_()
if __name__ == '__main__':
run_app()
Upvotes: 3