"""
OSに応じて実行中のウィンドウ一覧を取得し、指定したウィンドウのスクリーンショットを撮影するモジュール。
このモジュールは、Windows, macOS, Linuxの各OSに対応し、それぞれの環境で適切な方法を用いて
ウィンドウの操作とスクリーンショット撮影を行います。
関連リンク: :doc:`SS_window_usage`
"""
import platform
import subprocess
import time
import pyautogui
from PIL import Image
[ドキュメント]
def get_window_list():
"""
OSごとのウィンドウ一覧を取得します。
実行中のOS(Windows, macOS, Linux)に基づいて、現在開かれているウィンドウのタイトルリストを取得します。
Windowsでは`pygetwindow`、macOSではAppleScript、Linuxでは`wmctrl`コマンドを使用します。
:returns: 現在開かれているウィンドウのタイトル(文字列)のリスト。
:rtype: list[str]
"""
os_type = platform.system()
windows = []
if os_type == "Windows":
import pygetwindow as gw
windows = [w.title for w in gw.getAllWindows() if w.title.strip()]
elif os_type == "Darwin": # macOS
# AppleScriptを使って実行中のアプリケーション名を取得
script = 'tell application "System Events" to get name of every process whose background only is false'
proc = subprocess.run(['osascript', '-e', script], capture_output=True, text=True)
windows = [name.strip() for name in proc.stdout.split(',')]
elif os_type == "Linux":
# wmctrlコマンドを利用するのが最も一般的
try:
res = subprocess.run(['wmctrl', '-l'], capture_output=True, text=True)
for line in res.stdout.splitlines():
parts = line.split(None, 3)
if len(parts) >= 4:
windows.append(parts[3])
except FileNotFoundError:
print("Linuxで実行するには 'sudo apt-get install wmctrl' が必要です。")
return windows
[ドキュメント]
def focus_and_capture(target_title):
"""
指定されたタイトルを持つウィンドウをアクティブ化し、スクリーンショットを撮影して保存します。
OSによってウィンドウのアクティブ化方法とスクリーンショットの取得範囲が異なります。
Windowsでは`pygetwindow`を使用して指定ウィンドウを正確にアクティブ化し、その領域を撮影します。
macOSとLinuxでは、該当アプリケーション/ウィンドウを前面に表示しますが、
ウィンドウ固有の正確な領域取得が複雑なため、全画面または大きな領域を撮影する場合があります。
撮影された画像は、タイムスタンプを含むファイル名でPNG形式で保存されます。
:param target_title: アクティブ化してスクリーンショットを撮影するウィンドウのタイトル。
:type target_title: str
:returns: なし。スクリーンショットはファイルとして保存されます。
:rtype: None
"""
os_type = platform.system()
try:
if os_type == "Windows":
import pygetwindow as gw
win = gw.getWindowsWithTitle(target_title)[0]
win.activate()
time.sleep(1)
region = (win.left, win.top, win.width, win.height)
elif os_type == "Darwin": # macOS
# AppleScriptでアプリを前面に出す
subprocess.run(['osascript', '-e', f'tell application "{target_title}" to activate'])
time.sleep(1)
# macOSはウィンドウ単位の座標取得が複雑なため、全画面を撮ってから手動で切り抜くか、
# スクリーン全体をターゲットにするのが一般的です。
print("macOSでは画面全体を撮影します。")
region = None
elif os_type == "Linux":
# wmctrlでウィンドウをアクティブ化
subprocess.run(['wmctrl', '-a', target_title])
time.sleep(1)
# xwininfoなどで座標取得可能だが、ここでは簡易的に全体撮影を例示
region = None
# 撮影
ss = pyautogui.screenshot(region=region)
filename = f"ss_{int(time.time())}.png"
ss.save(filename)
print(f"保存成功: {filename}")
except Exception as e:
print(f"エラーが発生しました: {e}")
if __name__ == "__main__":
titles = get_window_list()
for i, t in enumerate(titles):
print(f"[{i+1}] {t}")
idx = int(input("\n番号を選んでください: ")) - 1
focus_and_capture(titles[idx])