[PYTHON] Set the environment variables required for PySide (Qt4) and PyQt (Qt5)

When making both Qt4 / Qt5 and PySide (Qt4 compatible, Qt5 compatible) / PyQt (Qt5 compatible) compatible, a little ingenuity was required around environment variables.

Prerequisite environment

Install Qt4 / Qt5

Install via Homebrew.

Qt4/Install Qt5(Homebrew)


$ brew install qt
$ brew install qt5

Install PySide

Since PySide could be installed via pip, install it under virtualenv.

Install PySide(pip)


$ mkvirtualenv -p python3 pyside
(pyside)$ mkvirtualenv 
(pyside)$ pip install PySide

Install PyQt

I also tried to install PyQt via pip, but I couldn't install it because it was already deleted.

Install PyQt(Failed with pip)


$ mkvirtualenv -p python3 pyqt
(pyqt)$ pip install PyQt5
Downloading/unpacking PyQt5
  Could not find any downloads that satisfy the requirement PyQt5
Cleaning up...
No distributions at all found for PyQt5
Storing debug log for failure in /Users/FGtatsuro/.pip/pip.log

Therefore, I decided to install PyQt via Homebrew. For troubles during installation, see here. PyQt itself was installed via Homebrew, but considering installing related libraries, create a virtualenv environment like PySide.

Install PyQt(Homebrew)


(pyqt)$ brew install pyqt5

Run PySide

I tried to run the PySide sample at here, but it failed to load the dynamic library and could not be executed.

Run PySide(Failure)


(pyside)$ python pyside_test.py
Traceback (most recent call last):
  File "pyside_test.py", line 6, in <module>
    from PySide.QtCore import *
ImportError: dlopen(/Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide/QtCore.so, 2): Library not loaded: libpyside.cpython-34m.1.2.dylib
  Referenced from: /Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide/QtCore.so
  Reason: image not found

The dynamic library you are trying to load is under site-package in virtualenv. It can be executed by adding the path to the environment variable DYLD_LIBRARY_PATH.

Run PySide(success)


(pyside)$ ls /Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide/libpyside.cpython-34m.1.2.dylib
/Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide/libpyside.cpython-34m.1.2.dylib
(pyside)$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide
(pyside)$ python pyside_test.py

Run PyQt

I tried to run the PyQt sample at here, but it fails to load the PyQt module.

Run PyQt(Failure)


(pyqt)$ python pyqt_test.py
Traceback (most recent call last):
  File "pyqt_test.py", line 4, in <module>
    from PyQt5.QtCore import *
ImportError: No module named 'PyQt5'

The cause is that the site-package of PyQt (sip on which + PyQt depends) installed via Homebrew is not visible from the virtualenv environment. It can be executed by adding the path to the environment variable PYTHONPATH.

Run PyQt(success)


(pyqt)$ export PYTHONPATH=$PYTHONPATH:/usr/local/opt/pyqt5/lib/python3.4/site-packages:/usr/local/opt/sip/lib/python3.4/site-packages
(pyqt)$ python pyqt_test.py

Switching environment variables

Up to this point, PySide / PyQt can be executed, but there are still problems when these coexist. If both DYLD_LIBRARY_PATH required for PySide and PYTHONPATH required for executing PyQt exist, PyQt execution fails. (Trouble loading the library?)

PyQt execution failure due to environment variable


(pyqt)$ env | egrep 'DYLD_LIBRARY_PATH|PYTHONPATH'
DYLD_LIBRARY_PATH=/Users/FGtatsuro/.homesick/repos/dotfiles/home/.virtualenvs/pyside/lib/python3.4/site-packages/PySide
PYTHONPATH=/usr/local/opt/pyqt5/lib/python3.4/site-packages:/usr/local/opt/sip/lib/python3.4/site-packages

(pyqt)$ python pyqt_test.py
Traceback (most recent call last):
  File "pyqt_test.py", line 5, in <module>
    from PyQt5.QtWidgets import *
RuntimeError: the PyQt5.QtCore module failed to register with the sip module

It can be executed by unsetting DYLD_LIBRARY_PATH, but it is very annoying to have to be aware of this variable every time you switch the virtualenv environment.

Therefore, I changed the configuration file of virtualenvwrapper so that the environment variables required when activating / deactivating the virtualenv environment of PySide / PyQt are exported / unset. .virtualenvs / postactivate is executed" after "activate, and .virtualenvs / predeactivte is executed "before" deactive. The judgment of the PySide environment depends on pip "under the virtualenv environment", and the timing of the judgment must be "after" entering the virtualenv environment and "before" leaving the virtualenv environment.

The conditions for judgment are as follows.

--PySide: PySide is installed with pip. --PyQt: The virtualenv environment name contains the string pyqt.

.virtualenvs/postactivate


#!/bin/bash
# This hook is run after every virtualenv is activated.

#DYLD if PySide is installed with pip_LIBRARY_Add the required path to your PATH.
if [ `pip freeze | grep PySide` ]; then
  # Now, I can use PySide on only 3.4.x environment
  VENV_PYSIDE_PATH=$VIRTUAL_ENV/lib/python3.4/site-packages/PySide
  if [ $DYLD_LIBRARY_PATH ]; then
    export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$VENV_PYSIDE_PATH
  else
    export DYLD_LIBRARY_PATH=$VENV_PYSIDE_PATH
  fi
fi

#The virtualenv environment name is"pyqt"If it contains, add the required path to PYTHONPATH.
if [ `basename $VIRTUAL_ENV | grep pyqt` ]; then
  # Now, I can use PyQt on only 3.4.x environment
  BREW_PYQT_PATH=`brew --prefix pyqt5`/lib/python3.4/site-packages:`brew --prefix sip`/lib/python3.4/site-packages
  if [ $PYTHONPATH ]; then
    export PYTHONPATH=$PYTHONPATH:$BREW_PYQT_PATH
  else
    export PYTHONPATH=$BREW_PYQT_PATH
  fi
fi

.virtualenvs/predeactivate


#!/bin/bash
# This hook is run before every virtualenv is deactivated.

#DYLD if PySide is installed with pip_LIBRARY_Remove the relevant path from the PATH.
if [ `pip freeze | grep PySide` ]; then
  # Now, I can use PySide on only 3.4.x environment
  VENV_PYSIDE_PATH=$VIRTUAL_ENV/lib/python3.4/site-packages/PySide
  export DYLD_LIBRARY_PATH=`echo $DYLD_LIBRARY_PATH | sed -e "s|:*$VENV_PYSIDE_PATH||g"`
  if [ -z $DYLD_LIBRARY_PATH ]; then
    unset DYLD_LIBRARY_PATH
  fi
fi

#The virtualenv environment name is"pyqt"If, exclude the relevant path from PYTHONPATH.
if [ `basename $VIRTUAL_ENV | grep pyqt` ]; then
  # Now, I can use PyQt on only 3.4.x environment
  BREW_PYQT_PATH=`brew --prefix pyqt5`/lib/python3.4/site-packages:`brew --prefix sip`/lib/python3.4/site-packages
  export PYTHONPATH=`echo $PYTHONPATH | sed -e "s|:*$BREW_PYQT_PATH||g"`
  if [ -z $PYTHONPATH ];then
    unset PYTHONPATH
  fi
fi

Since PyQt could not be installed via pip, I had to rely on the naming convention of the virtualenv environment for the judgment conditions. I'm a little disappointed with that, so I'll think about a good idea.

Recommended Posts

Set the environment variables required for PySide (Qt4) and PyQt (Qt5)
[Python] Measures and displays the time required for processing
The strongest PySide / PyQt development environment is also PyCharm
Select the required variables in TensorFlow and save / restore
Search for variables in pandas.DataFrame and get the corresponding row.
Set environment variables with lambda-uploader
Create a color picker for the color wheel with Python + Qt (PySide)
Prepare the environment for Atom for Pythonista
I set the environment variable with Docker and displayed it in Python
Set the environment variable PYTHONPATH on zsh
Prepare the development environment for keyhac for Mac
[Note] What to do if the Qt library conflicts between pyqt and opencv