mieki256's diary



2022/04/24() [n年前の日記]

#1 [python] PyAutoGUIを少しだけ試用

Python + PyAutoGUI でも操作の自動化ができるという話をどこかで見かけたので手元の環境で少し試用。

環境は Windows10 x64 21H2 + Python 3.9.12 64bit。

インストール。 :

インストールは以下。
pip install pyautogui
PyAutoGUI 0.9.53 がインストールされた。

また、以下のモジュールも依存関係でインストールされた。
  • MouseInfo 0.1.3
  • PyGetWindow 0.0.9
  • PyMsgBox 1.0.9
  • pyperclip 1.8.2
  • PyRect 0.2.0
  • PyScreeze 0.1.28
  • pytweening 1.0.4

PDFの自動翻訳をしやすくする処理が書けた。 :

色々試していたところ、昨日、AutoIt を使って作成したスクリプトと似たような処理を、PyAutoGUI でも書けた気がする。

_英文PDFの自動翻訳をAutoIt3を使って少し快適にした

_04_copypaste.py
import pyautogui as ag
import pygetwindow as gw
import pyperclip
import sys
import time

pdfviewer = "Reader DC"
deepl = "DeepL "


def activate_window(w):
    """Activate appli window."""
    try:
        w.activate()
    except Exception:
        w.minimize()
        w.restore()
    time.sleep(0.35)


def get_window(name):
    hwnds = gw.getWindowsWithTitle(name)
    w = None
    if hwnds != []:
        w = hwnds[0]
    else:
        print("Error: Not found %s" % name)
    return w


def main():
    w = get_window(pdfviewer)
    if w is None:
        sys.exit()

    activate_window(w)
    ag.hotkey("ctrl", "c")
    time.sleep(0.25)

    # replace CRLF to space
    txt = pyperclip.paste()
    newtxt = " ".join(txt.splitlines())
    # newtxt = txt.replace("\n", " ")
    pyperclip.copy(newtxt)

    # print(newtxt)

    w = get_window(deepl)
    if w is None:
        sys.exit()

    activate_window(w)
    ag.hotkey("ctrl", "a")
    time.sleep(0.25)
    ag.hotkey("delete")
    time.sleep(0.25)
    ag.hotkey("ctrl", "v")
    time.sleep(0.25)


if __name__ == '__main__':
    main()

後は、このPythonスクリプトを、何かしらのランチャーに登録して起動できるようにすれば、1クリックでPDF上の選択テキストを自動翻訳できるのではないかな…。

一応、tkinter も使って、GUI版も書いてみた。

_05_copypaste_gui.pyw

実行するとGUIウインドウとボタンが表示されるので、ランチャーに登録等をしなくても使えるかもしれない。

ウインドウのアクティブ化でハマった。 :

これは PyAutoGUI というより PyGetWindow の問題っぽいけど…。Windows10 x64 21H2上では、既に起動しているアプリのウインドウをアクティブにできないことに気づいた。.activate() を呼ぶと、タスクバー上のアプリアイコンは点滅するものの、アプリウインドウが最前面になってくれない。エラーを吐く。

Python 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

>>> import pyautogui as ag
>>> import pygetwindow as gw
>>> w = gw.getWindowsWithTitle("Chrome")[0]
>>> w.activate()
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    w.activate()
  File "C:\Python\Python39-64\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 246, in activate
    _raiseWithLastError()
  File "C:\Python\Python39-64\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 99, in _raiseWithLastError
    raise PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
pygetwindow.PyGetWindowException: Error code from Windows: 0 - この操作を正しく終了しました。
>>> 

以下の、最大化、最小化は動いたから、ウインドウのID?を取得し損ねているわけではないのだろう…。
>>> w.minimize()
>>> w.maximize()

ググったところ、「Windows上ではアプリウインドウのアクティブ化はできないから、最小化+最大化で目的を果たせ」という話も見かけた。AutoIt と比べると厳しいな…。

一応、以下の投稿によると、最小化+復元すれば目的が果たせるらしい。

_.activate() sometimes throw error - Issue #31 - asweigart/PyGetWindow - GitHub
_Activate does not work - Issue #36 - asweigart/PyGetWindow - GitHub
_When using IPython, window.activate() raises error. - Issue #29 - asweigart/PyGetWindow - GitHub

>>> w.minimize()
>>> w.restore()

目標のアプリウインドウを間違えてしまう問題。 :

スクリプト作成中に、間違ったアプリウインドウを取得されてしまってハマった。ウインドウタイトルに「DeepL」という文字列を含んだ他のアプリがあると、そのアプリに文字列を貼り付けようとしてしまう。今回は、「copypaste_deepl.py」という名前のファイルを Visual Studio Code (vscode) で編集しながら動作確認していたら、vscode上のソースを全部消されてしまって焦った…。

アプリウインドウを、ウインドウタイトルだけで探すのはちょっと問題があるようだなと…。

でもまあ、とりあえず今回は、"DeepL" じゃなくて "DeepL " でウインドウタイトルを検索させれば誤魔化せるかな…。

改行コードの置換で悩んだ。 :

クリップボード内の、改行コードを複数含んだ文字列に対して、改行コードをスペースに置換するあたりでハマった。replace() を使ったら、何故か上手く置換できなくて…。

とりあえず、splitlines() と join() でどうにかしてみたけれど…。replace() では処理できないのだろうか…?

    # replace CRLF to space
    txt = pyperclip.paste()
    newtxt = " ".join(txt.splitlines())
    pyperclip.copy(newtxt)

もしかして、"\n" と "\r\n" が混ざってしまっているのかな。

以下のページによると、改行コードの種類が不明な場合は .splitlines() と .join() を使うのもアリ、らしい。であれば、これでもいいのかな…。

_Pythonで改行を含む文字列の出力、連結、分割、削除、置換 | note.nkmk.me

以上、1 日分です。

過去ログ表示

Prev - 2022/04 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project