pyautogui는 파이썬을 이용해 키보드와 마우스를 조작할 수 있는 오토메이션 툴이다.
이미 수많은 고수분들이 pyautogui에 대한 글을 많이 올려주시고 있고,
구글링을 하면 수십만개의 글이 쏟아지므로 배우고 활용하는 데 큰 어려움은 없다.
다만 pyautogui는 공식적으로 (아직) 멀티모니터를 지원하지 않는다.
조금 더 구체적으로 말하면 메인모니터에서만 동작한다.
이게 왜 문제가 되냐면,
pyautogui는 멀티모니터를 지원하지 않음
→ windows는 어떤 프로그램이 최종 실행되고 종료된 모니터를 기억하고 있음
→ 만약 어떤 프로그램을 실행시켰는데 서브모니터에서 실행되면
→ pyautogui는 아무 역할을 하지 못함
근데 난 멀티모니터를 쓰잖아. 어떡하지?
답은 구글링에 있다.
https://github.com/asweigart/pyautogui/issues/321
(Use LocateOnScreen with Multiple Monitors)
위의 github 글을 보면 수많은 Genius들이 멋진 해결책을 올려주었다. 그 중 가장 잘 동작하는 것을 소개한다.
pascallo님이 2020년 5월 18일에 올려주신 방법.
참고로 굉장히 Specific한 경우로,
locateOnScreen 함수를 쓸 때 적용된다.
*locateOnScreen 함수는,
– 화면에서 특정 이미지가 있는지 확인한 뒤
– 해당 좌표를 반환해주는 함수이다.
문제 해결 핵심: pyscreeze 폴더 내부의 init.py를 수정
- pyscreeze 위치: python설치폴더/Lib/site-packages
- Windows에서만 동작함
1. 함수 _screenshot_win32은 아래와 같다.
def _screenshot_win32(imageFilename=None, region=None):
...
im = ImageGrab.grab()
위 코드에서 im = ImageGrab.grab() 을 아래와 같이 변경한다.
def _screenshot_win32(imageFilename=None, region=None):
...
im = ImageGrab.grab(all_screens= True)
2. 함수 locateOnScreen은 아래와 같다.
def locateOnScreen(image, minSearchTime=0, **kwargs):
...
retVal = locate(image, screenshotIm, **kwargs)
내부에 있는 retVal (아래 참고) 직전에 다음과 같은 내용을 추가한다.
def locateOnScreen(image, minSearchTime=0, **kwargs):
...
if retVal and sys.platform == 'win32':
# get the lowest x and y coordinate of the monitor setup
monitors = win32api.EnumDisplayMonitors()
x_min = min([mon[2][0] for mon in monitors])
y_min = min([mon[2][1] for mon in monitors])
# add negative offset due to multi monitor
retVal = Box(left=retVal[0] + x_min, top=retVal[1] + y_min, width=retVal[2], height=retVal[3])
retVal = locate(image, screenshotIm, **kwargs)
3. __init__.py의 최상단 import들이 모여있는 곳에 다음 내용을 추가한다.
if sys.platform == 'win32': # TODO - Pillow now supports ImageGrab on macOS.
import win32api # used for multi-monitor fix
from PIL import ImageGrab
4. 이제 locateOnScreen 함수를 쓰면 멀티모니터를 잘 왔다갔다 한다.
아래는 원문.