X11 アプリケーションを Python Xlib から操作
[Last Modified] (2019/06/02 15:24:59)

概要

Qt 等で開発された X11 アプリケーションを利用するためには X サーバのクライアントが必要になります。X サーバは仮想的に Xvfb コマンドで作成することができます。X サーバのクライアントには fluxbox などの X11 ウィンドウマネージャ、ssh -Xx11vnc、その他 Qt 等で開発された X11 アプリケーションがあります。

ここでは X サーバのクライアントを Xlib で作成して X11 アプリケーションを自動操作してみます。Python の Xlib 実装は python-xlib です。

インストール

pip 等でインストールできます。

sudo pip install python-xlib

スクリーンショットの取得

仮想ディスプレイ DISPLAY=:99 を作成します。

Xvfb :99 -screen 0 1024x768x24 -listen tcp -ac

GUI アプリケーションを接続します。

sudo apt install mesa-utils
DISPLAY=localhost:99 glxgears

以下のようにしてスクリーンショットを取得できます。

DISPLAY=localhost:99 ipython

RAW 画像は pillow(PIL) の Image.frombytes を利用して NumPy の ndarray に変換すると簡単です。

from Xlib.display import Display
from Xlib.X import ZPixmap
from PIL import Image
from numpy import asarray

# DISPLAY=:99 にはウィンドウマネージャが存在しないため root をキャプチャ対象とします。
display = Display()
screen = display.screen()
window = screen.root

# RAW 画像を取得して変換します。
rawimage = window.get_image(0, 0, 1024, 768, ZPixmap, 0xFFFFFFFF).data
image = Image.frombytes('RGB', (1024, 768), rawimage, 'raw', 'RGBX')

# ファイルに保存する場合は以下のようにします。
with open('./sample.png', 'w') as f:
    Image.fromarray(asarray(image)).save(f, 'PNG')

Uploaded Image

クリック、キーボード操作

仮想ディスプレイ DISPLAY=:99 を作成します。

Xvfb :99 -screen 0 1024x768x24 -listen tcp -ac

GUI アプリケーションを接続します。

sudo apt install x11-apps
DISPLAY=localhost:99 xeyes

仮想ディスプレイに VNC 接続して動作確認できるようにします。

x11vnc -display :99 -listen 0.0.0.0 -forever -xkb -shared -nopw
DISPLAY=:0 gvncviewer localhost::5900

以下のようにして左上の (0, 0) をマウスで左クリックできます。

DISPLAY=localhost:99 ipython

fake_input を利用します。番号の 1 は左クリックです。後に利用する xev でもマウスボタンの番号を確認できます。

from Xlib.display import Display
from Xlib.X import MotionNotify
from Xlib.X import ButtonPress
from Xlib.X import ButtonRelease
from Xlib.ext.xtest import fake_input

display = Display()
fake_input(display, MotionNotify, x=0, y=0)
fake_input(display, ButtonPress, 1)
display.sync()

Uploaded Image

同様にキーボードの操作を表現するためには以下のようにします。

DISPLAY=localhost:99 xev
DISPLAY=localhost:99 ipython

from Xlib.display import Display
from Xlib.X import KeyPress
from Xlib.X import KeyRelease
from Xlib.ext.xtest import fake_input

display = Display()
fake_input(display, KeyPress, 38) # 'a'
display.sync()

一連の GUI 操作の保存および再生

If you want to read the rest of this page

X11 アプリケーションを Python Xlib から操作

残り文字数は全体の約 55 %
なつかしのねこ
100 円
Related pages