pywinautoハマったところ
pythonのアプリケーションからwindows上のGUIを自動化するpywinautoライブラリを利用した際に、ハマった点を備忘録とする。
取り扱うもの
- python
- pywinauto
ハマった点
window上で操作したいItemが分かり難い
操作方法が分かり難い
どのように操作するのか?
例えば、pythonからPDFファイルのプリンタ設定を操作したいとき、 印刷ダイアログを開き、詳細設定ボタンを押下して詳細画面を開いてから、各種設定を実行する。
このとき、詳細設定画面には、様々なアイテム(テキスト・ボタン・チェックボックスなど)が存在するため、それらを識別して操作する必要がある。
pywinautoを利用すると、自動的にそれらを識別してくれるが、どのようなデータ構造で識別されているか知る必要がある。
pywinautoでデータ構造表示する
操作対象であるウィンドウを"window"オブジェクトすると、以下コードで表示できる。
print(window.dump_tree())
// // 表示結果 // Dialog - '印刷' (L76, T16, R615, B493) ['印刷Dialog', 'Dialog', '印刷'] child_window(title="印刷", class_name="#32770") | ------------------------ 省略 ------------------------ | GroupBox - '' (L380, T295, R587, B432) | ['ページ範囲GroupBox2', 'GroupBox4'] | child_window(class_name="Button") | | Static - '部数(&C):' (L389, T319, R496, B338) | ['部数(&C):', '部数(&C):Static', 'Static8'] | child_window(title="部数(&C):", class_name="Static") | | Edit - '1' (L504, T316, R536, B339) | ['Edit5', '部数(&C):Edit'] | child_window(title="1", class_name="Edit") | | CheckBox - '部単位で印刷(&O)' (L393, T359, R509, B378) | ['部単位で印刷(&O)CheckBox', '部単位で印刷(&O)', 'CheckBox2'] | child_window(title="部単位で印刷(&O)", class_name="Button") | | Static - '' (L463, T379, R580, B418) | ['Static9', '部単位で印刷(&O)Static'] | child_window(class_name="Static") | | UpDown - '' (L534, T316, R552, B339) | ['部数(&C):UpDown', 'UpDown'] | child_window(class_name="msctls_updown32") | | Button - '印刷(&P)' (L329, T456, R417, B482) | ['印刷(&P)Button', '印刷(&P)', 'Button3'] | child_window(title="印刷(&P)", class_name="Button") | | Button - 'キャンセル' (L424, T456, R512, B482) | ['キャンセル', 'キャンセルButton', 'Button4'] | child_window(title="キャンセル", class_name="Button") | | Button - '適用(&A)' (L518, T456, R606, B482) | ['適用(&A)Button', 'Button5', '適用(&A)'] | child_window(title="適用(&A)", class_name="Button") | | Button - 'ヘルプ' (L613, T456, R701, B482) | ['ヘルプ', 'Button6', 'ヘルプButton'] | child_window(title="ヘルプ", class_name="Button") | | TabControl - '' (L86, T50, R605, B449) | ['状態:TabControl', 'TabControl全般', 'TabControl'] | child_window(class_name="SysTabControl32")
構造の操作方法
例えば、印刷部数を変更したいとき、テキストボックスへ部数を入力する。
このとき、以下で表示されるアイテムを操作する。
// // 表示結果(抜粋) // | Edit - '1' (L504, T316, R536, B339) | ['Edit5', '部数(&C):Edit'] | child_window(title="1", class_name="Edit")
部数1と入力したいとき
window["部数(&C):Edit"].set_edit_text("1")
これは
'部数(&C):Edit'
をKeyとしてアイテムへアクセスし、メソッド(set_edit_text()など)でアイテムを操作している。
仮に、ほかの表示内容でアクセスを試みると、エラーとなる場合がある。
これは、Edit
やButton
や1
は、固有な名称でないか、可変となる名称であるためで、
それらをKeyとして利用することは、避けた方がよい。