1

I have a weird bug in my project that uses PySide for its Qt GUI, and in response I'm trying to test with simpler code that sets up the environment.

Here is the code I am testing with: https://stackoverflow.com/a/6906552/130164

When I launch that from my shell (python test.py), it works perfectly. However, when I run that script in Spyder, I get the following error:

Traceback (most recent call last):
  File "/home/test/Desktop/test/test.py", line 31, in <module>
    app = QtGui.QApplication(sys.argv)
RuntimeError: A QApplication instance already exists.

If it helps, I also get the following warning:

/usr/lib/pymodules/python2.6/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.

Why does that code work when launched from my shell but not from Spyder?


Update: Mata answered that the problem happens because Spyder uses Qt, which makes sense. For now, I've set up execution in Spyder using the "Execute in an external system terminal" option, which doesn't cause errors but doesn't allow debugging, either. Does Spyder have any built-in workarounds to this?

Community
  • 1
  • 1
Maxim Zaslavsky
  • 17,787
  • 30
  • 107
  • 173

4 Answers4

2

As Spyder also is a Qt application, it starts it's own QApplication. In the same process only one QApplication can exist, that's why you get the first error.

Sypder also uses matplotlib, and probably, therfore it already will have imported some of the mentioned modules, so that's why you get the second error.

So when usin it like that, you can't create your own QApplication or call matplotlib.use(). Or maybe it will work if you wrap these calls in try/except.

mata
  • 67,110
  • 10
  • 163
  • 162
  • That's what I suspected would be the issue. Do you know if there are any workarounds built into Spyder? For now, I've set up execution in Spyder using the "Execute in an external system terminal" option, which doesn't cause errors but doesn't allow debugging, either. Perhaps Spyder has some workaround to this? – Maxim Zaslavsky May 23 '12 at 00:05
  • I don't know spyder well enough, so besides catching the errors I have no idea. – mata May 23 '12 at 00:09
  • 1
    It is true that Spyder is running in a Qt application instance, but all of the Python console instances get executed in their own separate processes. – Jed Jun 29 '13 at 21:31
2

I have the same problem, and somewhere on stackoverflow was a solution.

Instead of

qApp = QtGui.QApplication(sys.argv)

Use

qApp = QtGui.QApplication.instance()
if qApp is None:
        qApp = QtGui.QApplication(sys.argv)
  • 1
    I got the same problem but with functional testing (using Qttest and unittest), your solution fix it well. Thanks. – gunzapper Jun 19 '14 at 10:41
1

It won't work in Spyder if you try to launch the application into an interactive console because that console is specially configured to import several scientific libraries, automatically show() matplotlib figures, and a few other details. Type scientific at the Spyder console prompt for more details. The result is effectively that a Qt application event loop is already running there.

To get your application to run inside of Spyder:

  1. Make sure Spyder is configured to open external consoles with PySide and not PyQt. This can be set from Tools>Preferences>Console>External modules>Qt-Python bindings library selection.
  2. With your script active in the editor, hit F6 to open the Run Settings dialog. Select the "Execute in a new dedicated Python interpreter" radio button instead of executing in the current interactive interpreter. Click OK. Now run the script by hitting F5. Debug the script by hitting Ctrl+F5.
Jed
  • 1,011
  • 1
  • 9
  • 15
1

The official Spyder wiki has a page on the subject: https://github.com/spyder-ide/spyder/wiki/How-to-run-PyQt-applications-within-Spyder. The gist of it is:

Important Note: Before running a PyQt application in Spyder, you need to change your Graphics backend to Automatic. You can do that by going to

Tools > Preferences > IPython Console > Graphics

After that, please restart your console kernels or Spyder itself for this change to take effect.

There's an explantion at the end:

The most common problem when running a PyQt application multiple times inside Spyder is that a QApplication instance remains in the namespace of the IPython console kernel after the first run. In other words, when you try to re-run your application, you already have a QApplication instance initialized.

Trying to remove that instance will probably cause your program to get stuck in a blocking while-loop, as suggested here, and using sys.exit() doesn't help since it's the same as trying to exit Python (and hence the IPython console).

A suggested solution is doing something like what @mata suggsets.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264