[업무 자동화 파이썬] Listener를 이용한 마우스 이벤트 제어

반응형
    반응형

    Listener를 이용한 마우스 이벤트

    리스너(listener)는 특정 이벤트가 발생할 때 프로그램은 해당 이벤트를 감지하고 움직이는 기능이 있는 이벤트 제어 도구입니다. Pyautogui는 이벤트 감지 기능이 없기 때문에 리스너와 함께 쓴다면 여러 시너지를 발휘할 수 있습니다.

    pynput 모듈에서 임포트할 수 있는데요. mouse와 keyboard가 따로 되어있는게 특징입니다.

    from pynput import mouse, keyboard
    mouse_listener = mouse.Listener(on_click=on_click)
    keyboard_listener = keyboard.Listnenr(on_click=on_click)

    메쏘드는 단 3개

    Listener에서 쓰는 메쏘드는 start(),join(),stop()으로 모두 3가지입니다. 이벤트 제어만 하기 때문에 시작(start), 대기(join), 중지(stop) 세가지로 이루어져 있습니다.

    마우스 특정 좌표 클릭 컨트롤

    마우스를 클릭할 때마다 마우스 위치 좌표를 가져오는 예제입니다.

    from pynput.mouse import Listener
    
    # 마우스 클릭 이벤트를 처리하는 함수
    def on_click(x, y, button, pressed):
        if pressed:
            print(f'마우스가 {x}, {y} 좌표에서 클릭되었습니다.')
    
    # 마우스 이벤트 리스너 생성
    with Listener(on_click=on_click) as listener:
        listener.join()  # 마우스 이벤트를 계속 감지

    with로 Listener를 실행시키면 멈추지 않고 클릭할 때마다 좌표를 찍어줍니다.

    하지만 이렇게 코드를 하면 중지가 안됩니다. 멈추질 않습니다. 

     

    종료 트리거 넣기

    종료 트리거를 넣어주어야 하는데 stop() 메쏘드를 써서 해결합니다. 그런데 그냥 with에 같이 넣으면 한번 동작하고 stop()으로 넘어가거나 join()에 의해 막히게 되니 stop()은 with에서 쓸 이유가 없습니다.

    이벤트 함수에서 stop을 만들어 트리거를 넣습니다. 아래 예제는 왼쪽 버튼을 누르면 좌표를 오른쪽 버튼을 누르면 종료하는 이벤트입니다.

    from pynput import mouse
    from pynput.mouse import Listener
    
    # 왼쪽 마우스 클릭 이벤트 핸들러 함수
    
    def on_click(x, y, button, pressed):
        if button == mouse.Button.left and pressed:
            print(f'왼쪽 마우스 클릭이 감지되었습니다. 좌표: ({x}, {y})')
    
        elif button == mouse.Button.right and pressed:
    
            print('프로그램을 종료합니다.')
            listener.stop()
    
    
    
    # 마우스 이벤트 리스너 생성
    with Listener(on_click=on_click) as listener:
    
        listener.join()  # 마우스 이벤트를 계속 감지
    

    참고로 pyatuogui의 pyautogui.FaILSAFE=TURE 를 사용하면 된다고 생각할 수 있는데 어림도 없습니다. 안됩니다.

    마우스 컨트롤의 리스너인데 키보드도 먹히는가

    마우스 컨트롤과 키보드 컨트롤에 각각 Listener가 있지만 하는 방법은 똑같습니다. 그래서 혹시 마우스 컨트롤에서 키보드로 트리거를 설정해도 그냥 해도 되지 않을까 이런 생각이 들 수 있습니다. 안타깝지만 그게 안 되네요. 저도 여러번해봤는데 안되서 많이 불편하네요. 안먹힙니다. 아쉽지만 각각 해주어야 합니다. 버전 업데이트가 되면 될수도 있습니다. 그러길 소망합니다.

    from pynput import keyboard, mouse
    
    # 키보드 이벤트 핸들러 함수
    def on_press(key):
        try:
            # 눌린 키가 ESC 키인 경우 프로그램 종료
            if key == keyboard.Key.esc:
                print('프로그램을 종료합니다.')
                # 마우스 리스너 중지
                mouse_listener.stop()
                # 키보드 리스너 중지
                return False
            else:
                # 눌린 키 출력
                print(f'키가 눌렸습니다: {key.char}')
        except AttributeError:
            # 특수 키 출력
            print(f'키가 눌렸습니다: {key}')
    
    # 마우스 클릭 이벤트 핸들러 함수
    def on_click(x, y, button, pressed):
        if button == mouse.Button.left and pressed:
            print(f'왼쪽 마우스 클릭이 감지되었습니다. 좌표: ({x}, {y})')
        elif button == mouse.Button.right and pressed:
            print('프로그램을 종료합니다.')
            # 키보드 리스너 중지
            keyboard_listener.stop()
    
    # 키보드 리스너 생성
    keyboard_listener = keyboard.Listener(on_press=on_press)
    
    # 마우스 리스너 생성
    mouse_listener = mouse.Listener(on_click=on_click)
    
    # 키보드 리스너 시작
    keyboard_listener.start()
    
    # 마우스 리스너 시작
    mouse_listener.start()
    
    # 키보드 리스너 대기
    keyboard_listener.join()
    
    # 마우스 리스너 대기
    mouse_listener.join()
    

    키보드와 마우스가 모두 동작을 멈추어야 해서 각각의 이벤트 리스너를 멈추게 해주어야 합니다. 이벤트 함수에서 종료 트리거가 나오면 마우스, 키보드가 모두 종료될 수 있도록 합니다.

    마치며

    리스너를 통해서 이벤트 제어가 가능해 여러작업들이 가능합니다. 업무 자동화, 매크로에 관심있으시다면 한번 써보시길 바랍니다.

     

    함께 보면 좋은 글

    [업무 자동화 파이썬] pyautogui로 마우스 제어하기

    비슷한 이미지 찾기 인공지능 사진 생성(feat. Clipdrop)

    웹크롤링을 시작하기 전에 준비할 것

    댓글

    Designed by JB FACTORY

    ....