時には立ち止まってみるのもいいよ

仕事の合間の息抜き。やってることは仕事と同じ。

dockerからPyQt(pyside2)なアプリを動かしてWindowsに表示する

dockerで実行しているブツをWindowsからGUIで操作したいとか言い出す人がいて、まぁ普通に考えるとnode.jsでもいれてブラウザでって感じなんだけど、誰でも使えるんじゃなくてdockerの中から見せる相手を制御したいとか言い出すので、だったらDocker内でGUIPyQtで作って、Windows側にXサーバー入れてDISPLAY指定してやればいいんじゃね?てことで。

 

あ。dockerのゲストOSはCentos7.7です。

 

Windows

Xサーバーってのが必要です。

今でもXサーバーってあるんだねぇ。Astec-Xとか使ってたなぁ。

 

今回使ったのは VcXsrv ってやつです。GPLです。

インストールはデフォルトのままで進めてOK。デスクトップに「XLaunch」アイコンができるので起動すると、設定画面が出ます。

 

f:id:poiuy56:20200930125321p:plain

VcXsrv設定1

Qtアプリを出したいだけなのでMultpleWindowsでOK. Xクライアントごとにウインドウを出してくれます。

f:id:poiuy56:20200930125420p:plain

VcXsrv設定2

Qtアプリは後から起動するので Start no client で起動。

f:id:poiuy56:20200930125454p:plain

VcXsrv設定3

Clipboardはお好みで。Native openglってのは何かよくわからん。スクショではこの2つはデフォルトのまま。

「Disable access control」はチェックをつけて認証なしで。

#Qt側から認証設定する方法がわからんかった。。

 

f:id:poiuy56:20200930130052p:plain

VcXsrv設定4

Save Configurationでこの設定をxxx.xlaunchファイルに保存できて、これを使って起動できるようになります。

 

完了を押すとXサーバーが起動してタスクトレイに入ります。

  

f:id:poiuy56:20200930142615p:plain

VcXsrvトレイ

マウスカーソルを合わせると、DISPLAY名と接続中のクライアント数が出ます。このDISPLAY名(ここでは "poiuy56:0.0" )はあとで docker 側から表示先を指定するのに使います。


 

 

 

Docker側

 

先にまとめ。今回追加したパッケージ一覧

# yum install -y python3

# pip3 install pyside2

# yum install -y xorg-x11-apps mesa-demos

# yum install -y xcb-util xcb-util-wm xcb-util-image xcb-util-keysyms xcb-util-renderutil libxkbcommon-x11

 

# yum install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts freetype-devel

# localedef -i ja_JP -f UTF-8 ja_JP.UTF-8

# echo 'LANG="ja_JP.UTF-8"' > /etc/locale.conf

 

以下、順を追って経緯を。

 

DISPLAY環境変数の設定

接続先のXサーバーを環境変数に登録します。VcXsrvのトレイアイコンに出てたやつ。

$ export DISPLAY=poiuy56:0.0

 

Python3インストール

python3入れます。cent7.7あたり(7.6か?)からpython3は標準リポジトリに入ったので

# yum install -y python3

でインストールできます。最新じゃないけど。

 

pyside2インストール

# pip3 install pyside2

dockerなんでpyenvとかいらんでしょ、というスタンス。

 

X-Window / OpenGL関連インストール 

少なくともXは入ってないとダメだよねってことで

# yum install -y xorg-x11-apps

 で依存関係を使ってマルっとインストール。

 

で、試しにこの状態で実行するとどうなるかってーと、

$ python3 xxxx.py

Traceback (most recent call last):

なんやかんや
ImportError: libGL.so.1: cannot open shared object file: No such file or directory

 OpenGLがいるんですかそうですか。

# yum install -y mesa-demos

で、どや!

 

xcb ? インストール

xcbが何者かわかってないけどロードできないそうなので。

$ python3 xxxx.py

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Aborted (core dumped)

 core dump ってせつないよね。

 

要するに、描画出力に必要なxcbプラグインは見つかったけどロードできないよと。

まぁまたライブラリが足りんのだろうなと思ったけど、lddコマンドで確かめようにもプラグインがどこに入ってるのかわからん。。

調べてみるとpyside実行するときにQT_DEBUG_PLUGINSを設定するとログが出るらしい。

 $ QT_DEBUG_PLUGINS=1 python3 xxxx.py

なんやかんや

Got keys from plugin meta data ("webgl")
QFactoryLoader::QFactoryLoader() looking at "/usr/local/lib64/python3.6/site-packages/PySide2/Qt/plugins/platforms/libqxcb.so"
Found metadata in lib /usr/local/lib64/python3.6/site-packages/PySide2/Qt/plugins/platforms/libqxcb.so, metadata=
{
"IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3",
"MetaData": {
"Keys": [
"xcb"
]
},
"archreq": 0,
"className": "QXcbIntegrationPlugin",
"debug": false,
"version": 331520
}


Got keys from plugin meta data ("xcb")
QFactoryLoader::QFactoryLoader() checking directory path "/usr/bin/platforms" ...
Cannot load library /usr/local/lib64/python3.6/site-packages/PySide2/Qt/plugins/platforms/libqxcb.so: (libxcb-icccm.so.4: cannot open shared object file: No such file or directory)

で、libxcb-icccm.so.4 が読めんと。ほかにもありそうなのでlddで確認。

$ ldd /usr/local/lib64/python3.6/site-packages/PySide2/Qt/plugins/platforms/libqxcb.so

すると足りないのは以下。

libxcb-icccm.so.4 => not found
libxcb-image.so.0 => not found
libxcb-keysyms.so.1 => not found
libxcb-render-util.so.0 => not found
libxkbcommon-x11.so.0 => not found
libxkbcommon.so.0 => not found
libxcb-icccm.so.4 => not found
libxcb-image.so.0 => not found
libxcb-keysyms.so.1 => not found
libxcb-render-util.so.0 => not found
libxkbcommon-x11.so.0 => not found
libxkbcommon.so.0 => not found

 で、これらをインストールする。

# yum install -y xcb-util xcb-util-wm xcb-util-image xcb-util-keysyms xcb-util-renderutil libxkbcommon-x11

 で、実行すると、、やたー!でたー!

 

。。。

 

あれ、、日本語が出てない。。

 

日本語フォント関連インストール

 # yum insatall ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts

 

で実行すると、エラーが。。

python3: symbol lookup error: /usr/local/lib64/python3.6/site-packages/PySide2/Qt/plugins/platforms/../../lib/libQt5XcbQpa.so.5: undefined symbol: FT_Get_Font_Format

 freetypeのバージョンが古いとこのエラーが出るらしい。ので、更新。

# yum install -y freetype-devel

エラーは出ないけど日本語も出ない。。

 

LANG設定

Dockerコンテナでは英語しか使えないので、言語設定の追加が必要でした。

# localedef -i ja_JP -f UTF-8 ja_JP.UTF-8

# echo 'LANG="ja_JP.UTF-8"' > /etc/locale.conf

 

 んで、

$ export LANG=ja_JP.UTF-8

$ python3 xxxx.py

  日本語も出たー!