본문 바로가기

python

이미지로 좌표찾기 및 마우스클릭 - pyautogui

반응형

안녕하세요. 오늘은 python 혼자서 이것저것 해보다가 알게된 부분에 대해 기록해 볼까 합니다.

 

일을 하다보면 정말 단순히 일정한 패턴으로 반복적으로 클릭만 하게 되는 경우가 있습니다. 이를 자동화할 수 있는 방법이 없을까? 라는 생각을 하였습니다.

 

거창하게 얘기해서 자동화이지, 사실은 PC화면상에서 어떤 버튼을 일정한 주기로 반복하여 누르기만 하면 되는데 이걸 내가 계속 하고 있자니 시간낭비가 심한 것 같아서 새로운 언어에 대한 공부도 할겸 python으로 이를 구현해 보기로 했습니다.

 

1. 목표

일단 제 목표는 계산기를 띄워서 자동으로 5, +, 9, =, 버튼을 각각 눌러서 결과인 14가 계산기에 표시되도록 하는 것이라고 하였습니다.

  • IDE는 PyCharm을 사용
  • gui는 tkinter를 사용

 

2. 메인화면 구현

아래와 같이 간단하게 적당한 크기의 화면하나에 label, button 을 위치시켰습니다.

import tkinter as tk
from tkinter import messagebox as msg
import pyautogui as pg
import time


win = tk.Tk()
win.title("Python GUI")

screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
win.geometry(f"{screen_width // 3}x{screen_height // 2}")

a_label = tk.Label(win, text="Find & Click")
a_label.grid(column=0,row=0)

action = tk.Button(win, text="Click Me!")
action.grid(column=1, row=0)

win.mainloop()

메인화면

 

3. 이미지로 버튼의 위치 찾기

계산기에서 필요한 부분을 캡쳐하여 PNG형식으로 저장하였습니다. 그리고 소스파일이 있는 경로에 복사했습니다.

찾을 이미지들

import pyautogui as pg

button5location = pg.locateOnScreen('5.png') # 이미지가 있는 위치를 가져옵니다. 
print(button5location)

위와 같이 pyautogui의 locateOnScreen 으로 이미지의 위치를 찾을 수 있습니다. 출력 결과는 Box 객체입니다.

이후 클릭하기 위해 찾은 결과의 Center 좌표를 구합니다.

import pyautogui as pg

button5location = pg.locateOnScreen('5.png')
point = pg.center(button5location) # Box 객체의 중앙 좌표를 리턴합니다. 
print(point)

출력결과는 Point 객체입니다.

 

4. 찾은 위치 마우스 클릭하기

마우스 클릭은 아래와 같은 방식으로 할 수 있습니다.

pyautogui.click()
pyautogui.click(button='right')
pyautogui.doubleClick()
pyautogui.click(clicks=3, interval=1) # 3번 클릭할건데 1초마다
pyautogui.click(x, y, button='left', clicks=1, interval=1) #x,y 좌표의 마우스 왼쪽클릭 1회

 

5. 계산기 자동으로 두드리기

이제 위의 개별 예제들을 조합하여 계산기를 두드립니다. 화면의 Click 버튼을 누르면 9+5=14라는 결과를 볼거에요.

import tkinter as tk
from tkinter import messagebox as msg
import pyautogui as pg
import time


win = tk.Tk()
win.title("Python GUI")

#화면을 적당한 크기로 늘이자
screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
win.geometry(f"{screen_width // 3}x{screen_height // 2}")

a_label = tk.Label(win, text="Find & Click")
a_label.grid(column=0,row=0)

pg.PAUSE = 1
pg.FAILSAFE = True

def click_me():
        action.configure(text="Clicked!")
        a_label.configure(foreground='red')
        a_label.configure(text='Find & Click')

        button9location = pg.locateOnScreen('9.png')
        if button9location == None:                             #찾지 못하면 알람 메시지 출력한다.
                msg.showinfo('alarm', 'button 9 Not found.')
                return

        point9 = pg.center(button9location)
        button5location = pg.locateOnScreen('5.png')
        if button5location == None:
                msg.showinfo('alarm', 'button 5 Not found.')
                return

        point5 = pg.center(button5location)

        buttonPlocation = pg.locateOnScreen('plus.png')
        if buttonPlocation == None:
                msg.showinfo('alarm', 'button plus Not found.')
                return

        pointPlus = pg.center(buttonPlocation)

        #위에서 찾은 포인트들을 차례로 클릭한다.
        pg.click(point9.x, point9.y, button='left', clicks=1, interval=1)
        time.sleep(1)
        pg.click(pointPlus.x, pointPlus.y, button='left', clicks=1, interval=1)
        time.sleep(1)
        pg.click(point5.x, point5.y, button='left', clicks=1, interval=1)
        time.sleep(1)

        buttonRlocation = pg.locateOnScreen('result.png')
        if buttonRlocation == None:
                buttonRlocation = pg.locateOnScreen('result1.png')
                if buttonRlocation == None:
                        msg.showinfo('alarm', 'button Result Not found.')
                        return

        pointResult = pg.center(buttonRlocation)
        pg.click(pointResult.x, pointResult.y, button='left', clicks=1, interval=1)


action = tk.Button(win, text="Click Me!", command=click_me)
action.grid(column=1, row=0)

win.mainloop()

 

6. 결과

결과화면

 

7. 마치며

오늘 연습한 내용으로 뭐를 할 수 있을까 생각해 봤습니다. 간단한 새로고침을 일정 시간마다 누르는 것 가능하지 않을까요? 새로 고침을 계속 누르며 현재 화면의 특정 이미지가 보인다면? 아니면 보이지 않게 되었다면 어떤 엑션을 하도록 한다... 

어쨌거나 귀찮은 일들을 줄이기 위한 툴을 만들기 위한 첫단계였습니다. 

앞으로 뭔가 쓸 만한게 나오면 이 곳에 기록해 보도록 하겠습니다.

감사합니다. 이 글을 읽으시는 모든 분들 오늘도 좋은 하루 되세요~~

반응형