LoginSignup
3
2

More than 1 year has passed since last update.

Qt for Windowsのアプリを相手にRPAするときのちょっといい話(=バッドノウハウ)

Posted at

RPAは技術的負債のバイバイン

 操作されるアプリの開発者としては、RPA friendlyにするより先にAPIを用意するでしょ常識的に考えて。APIのないところを無理やり強行突破するのがRPA。
 どんな世の中でも、こういう協調性ゼロの行為には、それなりの代償が伴う。
 協調的な開発(APIを使う普通のスタイル)が手数$n$に対して$a*n$の技術的負債を生むとすると(本当?)、RPAのような強行突破は、$a^n$の技術的負債を生む。
 技術的負債で破産する前に職場からトンズラする用意はOK?

Qt for Windowsはカスタムドローだらけ

 カスタムドローのコンポーネントはUI Automationなどでは操作できない。そこでpyautoguiなどのスクリーンショット+画像テンプレートマッチングを使って、いかにもRPAらしく強行突破するわけだが、数時間で早くもバッドノウハウを2つ発見したので、ここに記す。

操作したいウィンドウを最前面に持ってくる方法

 ずっと前から慣れっこになってしまっていて急には思い出せないかもしれないが、Windowsには昔々からずっと、「ウィンドウを最前面に持ってくる」という動作にバグがある。
 たとえば、タスクバーに出ている動作中アプリのアイコンをクリックしても最前面に出てこない場合があることを、どうか思い出していただきたい。そんなときは脊髄反射でAlt+TabするのがWindows使い。あまりにも長いこと体に染み付いた動作なので、いまさら意識するのは難しいかもしれない。
 スクリーンショットをキャプチャするときには、操作相手のウィンドウを最前面に持ってこなければならないので、このバグを回避する必要がある。PyGetWindowなら以下のとおり。

import pygetwindow as gw
w = None
for t in gw.getAllTitles():
    if 'Foo Bar' in t:
        w = gw.getWindowsWithTitle(t)[0]
        break

# bug workaround
w.minimize()
w.maximize()

 最小化して最大化する。以上。

Qt for Windowsのカスタムドローコンポーネントにクリックを認識させる方法

 pyautogui.moveTo()でマウスポインタを動かしてpyautogui.click()でクリック… では、たいていクリックを認識してくれない。
 Qt for Windowsの実装を調べていないので推測だが、「マウスポインタを高速で動かしている最中のクリックは誤入力として弾く」という機能があるのではないか。pyautogui.moveTo()で遠くから一発でクリック反応領域に飛び込んでくる、という動きに対しては、この機能が働いているのではないか。
 というわけで、人間が狙って操作しているらしいマウスポインタの動きを偽装する必要がある。クリックする地点がx, yとして、

pyautogui.moveTo(x - 2, y)
time.sleep(0.1)
pyautogui.moveTo(x - 1, y)
time.sleep(0.1)
pyautogui.moveTo(x - 0, y)
time.sleep(0.1)

 以下なにかまた見つけたら追記する。

3
2
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
3
2