WSLでGUI表示したいという話
こんな話,インターネットの海には無限に転がっている
転がっているからといってできるとは言ってないのがこの分野ですよね
以前にWSLのUbuntuからPyQt5で作ったアプリを立ち上げようとして,GUI周りで挫折したので,今回はリベンジ (コマンドプロンプトはやっぱり作業しづらい)
環境
- Windows10
- WSL1(Ubuntu)
- Python3.7→3.8
とりあえず実行しようとしてみる
GUIの基本(?)「とりあえず画面を出す」をするため,matplotlibを使ったプログラムでグラフを画面出力しようとしてみると...
エラーが出た
WSL UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
とりあえずこちらを参考にVcXsrvを導入
記事通りに終わらせて,いざ実行してみるとまたエラーが.
ModuleNotFoundError: No module named '_tkinter'
を参考に,
$ sudo apt install python3-tk
$ sudo apt install tk-dev
を実行.記事ではここでエラーが消えるかのように書いてあるが,ここではエラーが消えなかった.
ウンウン悩みつつ,短いエラー文とにらめっこすると...
import _tkinter # If this fails your Python may not be configured for Tk
コメント部分に気になることが書いてある.どうやらPython自体が現状だとTkに対応していないらしい.
なので,この時まで使っていたPython3.7の対話モードを立ち上げ,import tkinter
を走らせると,同じエラーが出た.
試しにPython3.8で同じことをしたところ...
エラーなくimportできた. なんで?
python3.8で先ほどのプログラムを指定して動かすと問題なく動いた.理由が分からない...
一応,WSLに乗っているPythonでは,3.8が現状の最新版である.そのせいなのか...?
PyQt5入りプログラムを動かす
なにはともあれmatplotlib入りのプログラムは動いたため,次は本命のPyQt5入りプログラムを実行する.
出たエラーは
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "***" even though it was found.
こちらを参考に,/usr/lib/rstudio/plugins/platforms/libqxcb.so
を探す.
ないことを期待していたのだが,存在していた.
理由が分からなくなったので,環境変数にQT_DEBUG_PLUGINS=1
を追加してもう一度実行した.
するとこの行が主原因らしいと分かった.
QObject::moveToThread: Current thread (***) is not the object's thread (***).
Cannot move to target thread (***)
どうやら,pipで入れていたopencvが,PyQtと競合してしまうらしい.
なので
$ pip uninstall opencv-python # 今あるライブラリを削除
$ pip install opencv-python-headless # headlessモードのライブラリを導入
これですべてのエラーが出なくなった.
まとめ
- Xserverを導入
- tk関係のパッケージをインストール
- PythonがそもそもTkを実行できるか確認
- OpenCV関係のライブラリはheadlessで入れる
ちなみに,matplotlib入りのプログラムを動かすとき,
import matplotlib
matplotlib.use('TkAgg')
を追加すると微妙なエラーも出ずに済む.
おわり.
その他参考