본문 바로가기
python

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

by sanglim 2023. 10. 11.
반응형

안녕하세요. 오늘은 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. 마치며

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

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

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

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

반응형