【簡単Python】画面操作ライブラリ「PyAutoGUI」をマルチモニターに対応させるシンプルな方法

アフィリエイト広告を利用しています。
QRコード
【QRコード】PC<--->スマホの切り替えにご利用ください
運営者・ポテ

いつもありがとうございます!

ノンプログラマー向け「Python解説シリーズ」へようこそ。

本稿では、「画面操作ライブラリ "PyAutoGUI" をマルチモニターに対応させるシンプルな方法」を解説いたします。


PyAutoGUI は、画面上の操作を 自動化するためのPythonの定番ライブラリです。マウスやキーボードの操作、スクリーンショットの取得など、人が手作業で行っていた操作を自動化できる非常に便利なライブラリです。

Information
  • ライブラリ
    特定の機能をもったコードの集合体です。 ソフトウェア作成における部品のようなものです。新しいアプリケーションを作成する際、ライブラリを使用することで、プログラマーは複雑なコードを自分で書く必要がなくなります。
  • GUI(グラフィカルユーザーインターフェース)
    ユーザーとコンピューターがコミュニケーションするための視覚的なインターフェースです。インターフェースとは接点のことです。ウィンドウ、ボタン等のグラフィカルな要素を使用してユーザーとコンピューターがコミュニケーションできるようにします。

しかし、この PyAutoGUIには、ひとつ欠点があります。それは、マルチモニターに対応していないことです。マルチモニター環境での作業が当たり前になってきている昨今、この制限は無視できません。

なんとかマルチモニターに対応させられないか ──

そんな課題を抱える方に向けて、シンプルで具体的な解決方法をお届けします。

Python を活用して、自身やコミュニティに適した改善ツールを作成し、仕事量は半分に、成果は 2 倍にしていきましょう。初心者の方にも理解しやすいよう、分かりやすく解説していきます。ぜひ、ご覧ください。

Pythonの画面操作ライブラリ「PyAutoGUI」をマルチモニタに対応させるシンプルな方法

前提の画面構成

下図のようなモニター構成を例にとります。メインモニター1の左側にサブモニター2が接続されています。

Windows のディスプレイ設定画面。モニター1(青)が右側、モニター2(灰色)が左側に並んで表示されている。
画面構成

まず、PyAutoGUI の通常の挙動を確認

まずは、PyAutoGUI の通常の挙動について解説します。分かりやすく示すために、画面のスクリーンショットを取得し、画像ファイルとして保存するシンプルなコードを例として取り上げます。以下のコードをご覧ください。

# ライブラリのインポート
import pyautogui


if __name__ == '__main__':

    # スクリーンショットを保存
    pyautogui.screenshot('screenshot.png')
Information

if name == 'main':
このファイルを直接実行したときだけ、その下のコードを動かす、という意味のコードです。Python はファイルを実行する際、__name__ という特別な変数を設定します。ファイルを直接実行した場合、その変数は__main__ になり、他のスクリプトにインポートされた場合はファイル名になります。if __name__ == __main__: によって、インポート時にコードが勝手に実行されるのを防ぎ、再利用可能なスクリプト設計とすることができます。

このコードを実行すると、保存された画像は次のようになります。サブモニターが接続されているにもかかわらず、メインモニターの画像のみがキャプチャされます。

プライマリモニターの全画面をキャプチャした Windows デスクトップのスクリーンショット。
screenshot.png

このように、PyAutoGUI は、マルチモニターに対応していません

PyAutoGUI をマルチモニターに対応させる方法

次に、PyAutoGUI をマルチモニターに対応させる方法を解説します。同様に、画面のスクリーンショットを取得し、画像ファイルとして保存するコードを例として取り上げます。以下のコードをご覧ください。

# ライブラリのインポート
import pyautogui
from PIL import ImageGrab


def grab_path(*args, **kwargs):
    kwargs["all_screens"] = True
    return _original_grab(*args, **kwargs)


if __name__ == '__main__':
    # 元のImage.Grab を取得
    _original_grab = ImageGrab.grab

    # ImageGrab.grab を grab_patch に置き換え
    ImageGrab.grab = grab_path

    # スクリーンショットを保存
    pyautogui.screenshot('screenshot_all_monitors.png')

このコードを実行すると、次のようにサブモニターを含む画面全体のスクリーンショットが保存されます。

screenshot_all_monitors.png
運営者・ポテ

解説していきます。

# ライブラリのインポート
import pyautogui
from PIL import ImageGrab

ここでは、スクリーンショットを取得するために必要なライブラリを読み込んでいます。

  • PyAutoGUI
    マウス操作、キーボード操作、画面のキャプチャなどを行うためのライブラリです。
  • ImageGrab
    PyAutoGUIの内部で使われている画面キャプチャ専用のライブラリです。つまり、PyAutoGUIは、ImageGrab を使用して画面キャプチャ処理を行っています
def grab_path(*args, **kwargs):
    kwargs["all_screens"] = True
    return _original_grab(*args, **kwargs)

ここでは、ImageGrab.grab() に対して、マルチモニター対応の設定を強制的に追加する関数grab_path()を定義しています。

この関数は、もともとの ImageGrab.grab() に渡される引数をすべて受け取り、それをそのまま渡し直す構造になっています。

  • *args は、「位置引数」(キーワードを付けずに渡される引数)をまとめて受け取る記法です。たとえば grab(100, 200) のように、何の名前もつけずに渡される引数が該当します。
  • **kwargs は、「キーワード引数」(名前を付けて渡される引数)をまとめて受け取る記法です。たとえば grab(all_screens=True) のように、キーワードをつけて渡される引数はここに入ります。
  • kwargs["all_screens"] = True は、関数が呼び出されたときにどんな引数が渡されていても、all_screens=True という設定をあとから強制的に追加するという意味です。例えば、すでに all_screens が設定されていても、ここで強制的に True に上書きされます。
  • _original_grab(*args, **kwargs) は、元の ImageGrab.grab() 関数を呼び出す部分です。変更した引数(all_screens=True を加えた状態)を使って、画面キャプチャ処理を実行しています。

このようにして、grab_path() は「全モニターをキャプチャするようにした、ImageGrab.grab() の代わり」として機能します。

Information

このように既存の関数を一時的に差し替えて動作を変更する方法は「モンキーパッチ(monkey patch)」と呼ばれます。

if __name__ == '__main__':
    # 元のImage.Grab を取得
    _original_grab = ImageGrab.grab

    # ImageGrab.grab を grab_patch に置き換え
    ImageGrab.grab = grab_path

    # スクリーンショットを保存
    pyautogui.screenshot('screenshot_all_monitors.png')

ここでは、先ほど定義した grab_path() を実際に使うための準備と、スクリーンショットの保存処理を行っています。

  • if __name__ == '__main__': は、「このファイルが直接実行されたときだけ、以下の処理を行う」という意味の Python の基本構文です。他のスクリプトにインポートされたときには実行されません。
  • _original_grab = ImageGrab.grab は、元の関数を一時的に変数に保存するための処理です。あとで元に戻すための準備です。
  • ImageGrab.grab = grab_path によって、画面キャプチャ処理を grab_path() にすり替えています。これにより、PyAutoGUI のスクリーンショット機能がマルチモニター対応になります。
  • pyautogui.screenshot('screenshot_all_monitors.png') は、マルチモニター全体のスクリーンショットを取得し、ファイルとして保存する処理です。

このようにして、PyAutoGUIをマルチモニターに対応させることができます。

PyAutoGUIの設定を元に戻すには

上述のマルチモニターに対応させる方法は、ImageGrab の動作を書き替えているため、他のコードやライブラリが ImageGrab を使っている場合、意図しない挙動になる可能性があります。そのため、必要な処理が終わったら、元の(デフォルトの)状態に戻したい場合には、次のように記述します。

# ライブラリのインポート
import pyautogui
from PIL import ImageGrab


def grab_path(*args, **kwargs):
    kwargs["all_screens"] = True
    return _original_grab(*args, **kwargs)


if __name__ == '__main__':
    # 元のImage.Grab を取得
    _original_grab = ImageGrab.grab

    # ImageGrab.grab を grab_patch に置き換え
    ImageGrab.grab = grab_path

    try:
        # スクリーンショットを保存
        pyautogui.screenshot('screenshot_all_monitors.png')
    finally:
        # 元の ImageGrab.grab に戻す
        ImageGrab.grab = _original_grab
運営者・ポテ

以上で解説は終了です。


Python プログラミングスキルアップのための参考情報

ここでは参考図書を紹介いたしますが、これに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心からお祈りしております。


「独学プログラマー」というPythonを題材にした書籍は大変勉強になりました。Pythonの技術解説だけにとどまらず、プログラミングの魅力や基本的な知識、思考法、仕事の進め方まで幅広く学べます。


こちらの記事でも紹介しております。もしよろしければご覧ください。


また、Pythonに関する書籍は多数出版されています。興味のある方は、チェックしてみてください。

\チェックしてみよう/

\チェックしてみよう/

\チェックしてみよう/

QRコード
【QRコード】PC<--->スマホの切り替えにご利用ください

おわりに

運営者・ポテ

ご覧いただきありがとうございました!

本稿では、「画面操作ライブラリ "PyAutoGUI" をマルチモニターに対応させるシンプルな方法」を解説いたしました。

お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。

皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。

なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。

この記事を書いた人

運営者・ポテソフトデザイン工房|日々の業務にちょうどいい自動化を
■人生を追求する凡人 ■日本一安全で、気の向くままに自分の時間を過ごせる、こだわりのキャンプ場を作るのが夢 ■ソフトデザイン工房代表(個人事業者) - 業務設計&業務支援アプリケーション作成サービスを展開 ■人生は時間そのもの。ひとりでも多くの人が「より良い人生にするために時間を使って欲しい」と願い、仕事のスキルの向上、余暇の充実、資産形成を研究。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です