ipython / ipykernel

IPython Kernel for Jupyter
https://ipykernel.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
622 stars 359 forks source link

Problems with PySide2 integration #497

Open akloster opened 4 years ago

akloster commented 4 years ago

There are two popular Python bindings for Qt 5: PyQt5 and PySide2. For various reasons, it is sometimes necessary to use PySide2. For example FreeCAD prefers PySide2.

So far I haven't been successful to integrate PySide2 inside a jupyter kernel. Even the simplest examples with "%gui qt5" fail, in various scenarios with Ubuntu system packages, conda environments and so on.

What is the situation with PySide2 currently? Is it possible at all?

akloster commented 4 years ago

Particularly, with a new conda environment, Python 3.7, and only PySide2 installed:

ImportError: 
    Could not load requested Qt binding. Please ensure that
    PyQt4 >= 4.7, PyQt5, PySide >= 1.0.3 or PySide2 is available,
    and only one is imported per session.

    Currently-imported Qt library:                              None
    PyQt4 available (requires QtCore, QtGui, QtSvg):            False
    PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): False
    PySide >= 1.0.3 installed:                                  False
    PySide2 installed:                                          True
    Tried to load:                                              ['pyqt5']

So it knows PySide is installed, but chooses pyqt5 anyway...

stukowski commented 2 years ago

I encountered the same problem as you and found a workaround. To load and activate the PySide2 package instead of PyQt5, I run

import os
os.environ['QT_API'] = 'pyside2'
%gui qt4

in my Jupyter notebook.

The trick is to run %gui qt4 instead of %gui qt5, unlike one would expect. Only then will the environment variable QT_API take effect. Take a look at the, in my eyes, bad implementation of the loop_qt5() function:

https://github.com/ipython/ipykernel/blob/fdda069bba36cafcc25df4d2353b26fbdb9e4d15/ipykernel/eventloops.py#L123-L126

It overrides the QT_API environment variable before delegating all further work to loop_qt4(). So it makes sense to bypass loop_qt5 and invoke loop_qt4 directly.

stukowski commented 2 years ago

This seems to be a duplicate of issue #398.

ccordoba12 commented 2 years ago

@akloster, could you submit a PR to fix the bug you found? Thanks!