python 다중 모니터 창 이동
다중모니터 사용시 프로그램을 창 이동하는 프로그램입니다. 기존 스트림덱에서 사용할려고 만들었습니다.
모니터 구분 및 창 이동을 위해서는 win32api , win32gui 가 필요합니다.
일단 pip 로 설치합니다.
pip install pywin32
윈도우의 경우 설치가 안되시는 분들은 https://www.lfd.uci.edu/~gohlke/pythonlibs/#pywin32 사이트에서 python 버전과 비트에 맞는 whl 파일을 다운받아 설치하시면 됩니다.
pip C:\경로\xxx.whl
전체 소스입니다.
from win32 import win32api, win32gui
from operator import itemgetter
class MoveMonitor():
def __init__(self, parent = None):
monitor = win32api.EnumDisplayMonitors()
self.monitorMap = list()
for info in monitor:
# 주 모니터와 서브 모니터 구분
if info[2][0] == 0 and info[2][1] == 0:
monitorType = "P"
else :
monitorType = "S"
self.monitorMap.append({'type': monitorType, 'handle' : info[0], 'left' : info[2][0], 'top' : info[2][1]})
'''
@ 현재 선택된 창의 타이틀과 핸들을 돌려준다.
@ list : title, handle, left, top, width, height
'''
def getActiveWindowHandle(self):
def callback(hwnd, hwnd_list: list):
activeTitle = win32gui.GetWindowText(win32gui.GetForegroundWindow())
title = win32gui.GetWindowText(hwnd)
if win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd) and title:
if title == activeTitle:
rect = win32gui.GetWindowRect(hwnd)
hwnd_list.append((title, hwnd, rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]))
output = []
win32gui.EnumWindows(callback, output)
return output[0]
def moveWindow(self, direction):
self.direction = direction
tmpMonitorMap = self.monitorMap
# 선택된 프로그램의 핸들값
hwnd = self.getActiveWindowHandle()
# 선택된 프로그램의 현재 모니터 위치
thisMonitorHandle = win32api.MonitorFromWindow(hwnd[1])
# 방향에 따라 list 를 정렬하여 값을 추출
if direction == 'left':
# left 내림차순 정렬
sortedData = sorted(self.monitorMap, key=itemgetter('left'), reverse=False)
elif direction == 'right':
sortedData = sorted(self.monitorMap, key=itemgetter('left'), reverse=True)
elif direction == 'up':
sortedData = sorted(self.monitorMap, key=itemgetter('top'), reverse=False)
elif direction == 'down':
sortedData = sorted(self.monitorMap, key=itemgetter('top'), reverse=True)
# 창 이동
win32gui.MoveWindow(hwnd[1], sortedData[0]['left'], sortedData[0]['top'], hwnd[4], hwnd[5], 1)
test = MoveMonitor()
test.moveWindow('down')
win32 함수에 대한 설명은 http://timgolden.me.uk/pywin32-docs 사이트를 참고하시면 됩니다.
win32api.EnumDisplayMonitors() 함수를 이용하여 현재 시스템의 모니터 갯수와 정보(해상도, 위치) 를 확인합니다.
결과값은 다음과 같습니다.
[(PyHANDLE:65537, PyHANDLE:0, (0, 0, 1920, 1080)), (PyHANDLE:65539, PyHANDLE:0, (-1920, 1, 0, 1081))]
1 : 모니터에 대한 핸들값입니다.
2 : unknown
3 : 위치와 해상도에 관한 값입니다. 앞의 2개 값만 사용합니다. ( left, top, width, height )
0, 0 이 주모니터입니다. left 가 - 일 경우 주 모니터 왼쪽에 위치 한다고 보면 됩니다.
모니터가 상하로 위치할 경우 top 의 +- 값을 보고 판단합니다.
그리고 이동 할려고 하는 창의 정보를 가져옵니다.
getActiveWindowHandle 함수를 이용하여 현재 포커싱된 창의 핸들값과 크기 정보를 가져옵니다.
마지막으로 win32gui.MoveWindow 함수를 이용하여 해당 모니터의 좌측 상단을 기준으로 이동합니다.
전 이 class 를 스트림덱에 적용하여 사용하고 있습니다.
다음에는 큰 모니터 사용자를 위한 창 분할 기능을 만들도록 하겠습니다.
감사합니다.