20
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PySide(Qt4)とPyQt(Qt5)に必要な環境変数をセットする

Last updated at Posted at 2014-11-12

Qt4/Qt5およびPySide(Qt4対応,Qt5に対応していないようなので)/PyQt(Qt5対応)を両立する際、環境変数まわりで少し工夫が必要だった。

前提環境

  • OS X(10.9.5)
  • virtualenvwrapper
  • Homebrew

Qt4/Qt5のインストール

Homebrew経由でインストールする。

Qt4/Qt5のインストール(Homebrew)
$ brew install qt
$ brew install qt5

PySideのインストール

PySideはpip経由でインストール可能だったため、virtualenv下にインストールする。

PySideのインストール(pip)
$ mkvirtualenv -p python3 pyside
(pyside)$ mkvirtualenv 
(pyside)$ pip install PySide

PyQtのインストール

PyQtも同様にpip経由でインストールを試みたところ、既に削除されたのかインストールできなかった。

PyQtのインストール(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

そのため、PyQtはHomebrew経由でインストールすることとした。インストール時のトラブルはこちら。なおPyQt自体はHomebrew経由でインストールしたが、関連するライブラリをインストールすることを考えて、PySideと同様にvirtualenv環境は作っておく。

PyQtのインストール(Homebrew)
(pyqt)$ brew install pyqt5

PySideの実行

ここにあるPySideのサンプルを動かそうとしたが、動的ライブラリの読み込みに失敗し実行できない。

PySideの実行(失敗)
(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

読み込もうとしている動的ライブラリはvirtualenvのsite-package下にある。そのパスを環境変数DYLD_LIBRARY_PATHに追加することで実行できる。

PySideの実行(成功)
(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

PyQtの実行

ここにあるPyQtのサンプルを動かそうとしたが、こちらはPyQtのモジュールの読み込みに失敗する。

PyQtの実行(失敗)
(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'

Homebrew経由でインストールしたPyQt(+PyQtが依存しているsip)のsite-packageが、virtualenv環境から見えていないのが原因。そのパスを環境変数PYTHONPATHに追加することで実行できる。

PyQtの実行(成功)
(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

環境変数の切り替え

ここまででPySide/PyQtの実行はできたが、これらを共存するとなるとまだ問題がある。PySideに必要なDYLD_LIBRARY_PATHとPyQtの実行に必要なPYTHONPATHが両方存在した場合、PyQtの実行に失敗する。(ライブラリの読み込みトラブル?)

環境変数によるPyQt実行の失敗
(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

DYLD_LIBRARY_PATHをunsetすれば実行可能になるが、virtualenv環境を切りかえるたびにこの変数を意識しなくてはならないのは非常に面倒に感じる。

そこでPySide/PyQtのvirtualenv環境をactivate/deactivateした際に必要な環境変数をexport/unsetするようにvirtualenvwrapperの設定ファイルを変更した。.virtualenvs/postactivateはactivate「後」に実行され、.virtualenvs/predeactivteはdeactive「前」に実行される。PySide環境の判定が「virtualenv環境下の」pipに依存しており、判定のタイミングはvirtualenv環境に入った「後」とvirtualenv環境から出る「前」でなくてはならない。

判定の条件は次の通り。

  • PySide: pipでPySideがインストールされている。
  • PyQt: virtualenv環境名に文字列pyqtを含む。
.virtualenvs/postactivate
#!/bin/bash
# This hook is run after every virtualenv is activated.

# PySideがpipでインストールされていれば、DYLD_LIBRARY_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

# virtualenv環境名が"pyqt"を含んでいれば、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.

# PySideがpipでインストールされていれば、DYLD_LIBRARY_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

# virtualenv環境名が"pyqt"を含んでいれば、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

PyQtをpip経由でインストールすることができなかったため、判定の条件をvirtualenv環境の命名規則に頼らざるを得なかった。その点が少し残念なので、いいアイデアがないか考える。

20
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?