概要
ウインドウのタイトルをもとに特定のウインドウをアクティブ化する。
pywin32はWindows環境でしか使えないので、x11のコマンドをsubprocessで実行する。
環境
x11が標準でインストール済みのraspbianで実行
コード
import subprocess
def active_window(title):
# xwininfoを用いて対象アプリのウインドウIDを取得する
# https://hk29.hatenablog.jp/entry/2021/08/15/182010 から引用
cmd_list = ['xwininfo', '-root', '-tree', '|', 'grep', title]
cmd = ' '.join(cmd_list)
result = subprocess.run(cmd, encoding='UTF-8', shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
app_id = result.stdout.split()[0]
# xdotoolを用いて、ウインドウIDから対象アプリをアクティブ化
cmd_list = ['xdotool', 'windowactivate', app_id]
cmd = ' '.join(cmd_list)
subprocess.run(cmd, shell=True)
if __name__ == '__main__':
active_window('Minecraft')
詳細
subprocessのざっくりした理解
subprocessは他アプリの実行ができるライブラリ。
subprocess.run("実行コマンド")
やらsubprocess.popen("実行コマンド")
やらでコマンドの実行ができる。
run
は起動したアプリを終了させるまで処理が進まないのに対して、popen
は終了を待たずに処理が進む。
上記のコードはrun
で実行しているが、コードから他のアプリを起動してpyautoguiを使ってそのアプリの操作したいとかになるとpopen
でやった方がいいのかもしれない。
使用したsubprocessのオプション
オプションをshell=True
とするとシェルからコマンドを実行してくれる。
デフォルトはshell=False
で、実行コマンドにexeファイル等のパスを入れるとそのまま実行してくれる
stdout=subprocess.PIPE, stderr=subprocess.PIPE
とすることで、実行したコマンドを戻り値として取得することができる。このとき、encoding='UTF-8'
としておかないと出力がバイナリ値で返ってくる。
xwininfoを使ってウインドウIDを取得する
実際に使ったコードはhttps://hk29.hatenablog.jp/entry/2021/08/15/182010 の引用
cmd_list = ['xwininfo', '-root', '-tree', '|', 'grep', title]
cmd = ' '.join(cmd_list)
result = subprocess.run(cmd, encoding='UTF-8', shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
app_id = result.stdout.split()[0]
xwininfo
はウインドウ情報の取得に使えるx11のライブラリ。
オプションでウインドウのサイズや位置を取得することもできる。
参考url:https://kledgeb.blogspot.com/2012/12/ubuntu-xwininfo-1.html
-name
オプションでタイトルを指定して使うのが楽だけど、完全一致でないと使えなくなるので'-root', '-tree'
オプションでルートウインドウに連なるすべてのウインドウ情報を取得して、その中から特定の文字列を含むウインドウのみを| grep "タイトル"
で抽出している。
この出力はウインドウID以外の情報も含む文字列だが、splitした1つ目でIDが取得できる。
タイトルがスペースを含んでいるとそこも分割されるので、サイズや位置を取得したい場合は注意が必要。
xdotoolを使って対象アプリをアクティブ化
cmd_list = ['xdotool', 'windowactivate', app_id]
cmd = ' '.join(cmd_list)
subprocess.run(cmd, shell=True)
xdotoolはウインドウの操作に使えるx11のライブラリ。
参考url:https://mackro.blog.jp/archives/9856283.html
最後に
非Windows環境で指定したアプリをアクティブ化することができるようになった。
今後、pyautoguiを使った作業の自動化をしていくつもりだけども、pyautoguiの使い方を解説するサイトでは同時にpywin32も使われがちなので似たようなことをまたやることになるかも。