지난 포스트에서 pynput.mouse 를 다뤄봤습니다.
pynput.keyboard는 pynput의 키보드에 대응하는 모듈입니다.
모듈이라고 어렵게 생각할 필요가 없습니다.
컴퓨터 프로그래밍을 배우는데
가장 큰 장벽중에 하나가 테크 용어입니다.
아마 IT 분야가 현재 세계에서 가장 많은
새로운 용어를 만들어내는 분야일 것 입니다.
이 용어를 새로 만드는 것은
IT사람들이 전통적으로 좋아하는 일입니다.
때문에 사람들을 혼란스럽게 하거나 욕도 많이 먹죠.
최근에도 메타버슨가 뭔가 떠들고 있던데
그냥 가상현실입니다.
용어를 만드는 것은
거기에 의미를 부여하고 있다는 것입니다.
그 의미는 과학자와 공학자들이
비즈니스맨들과 만나서 부여합니다.
비즈니스맨들은 돈이 되니까 뛰어들고
과학자들은 그냥 운명처럼 뛰어듭니다.
그들이 항상 맞지는 않죠.
요점은 용어를 어려워하지 말라는 말입니다.
IT용어는 막상 풀어서 설명하면
아무것도 아닌 것이 90% 이상입니다.
일부러 어려우라고 만든 것은 아닌데
어쨋든 머리를 조금 굴려야 하지만
그 전에 용어에 익숙해져야 합니다.
IT는 용어를 이해하면 다른 것은 거의 다 이해가 됩니다.
자 이번엔 파이썬으로 키보드를 컨트롤 해보겠습니다.
아래는 공식문서를 참고하여 작성한 코드스니펫입니다.
from pynput.keyboard import Key, Controller
import time
kbControl = Controller()
time.sleep(1)
kbControl.press(Key.space)
kbControl.release(Key.space)
kbControl.press('a')
kbControl.release('a')
kbControl.press('D')
kbControl.release('D')
with kbControl.pressed(Key.shift):
kbControl.press('z')
kbControl.release('z')
kbControl.type('\nHello my Friend')
pynput.keyboard에서
Key와 Controller를 사용합니다.
모듈을 다룰 때 주의할 점은...
from ~ import ~ 에서 가져오는 것은 이름공간입니다.
C++ 에서 부터 있는 개념이죠. namespace
파이썬이나 C# 등에서 마찬가지로
이름공간이나 모듈에서 가져오는 것을
너무 딱 맞아떨어지게 되있지는 않습니다.
왜냐하면 이름공간은
기계를 위해 설계한게 아니라
인간을 위해 설계한 시스템이기 때문입니다.
자바나 C같은 정적언어에서는
컴파일러가 변수의 이름을 문자열로 저장하지 않습니다.
사람이 변수이름을 멋드러지게
'myVariable' 같이 지었다 하더라도
컴파일러는 그들만의 규칙으로
예를 들어 a1, a2, a3 이런 식으로
스택메모리에 관한 테이블과 인덱스를 보관하는 식입니다.
즉 컴파일러는 우리가 명명한 변수의 이름을
다시 정의하므로 이름이 겹칠일이 없습니다.
(런타임은 별도)
하지만 인간은 소스코드를 작성하면서 혼동합니다.
myNumber 가 어디 파일의 myNumber냐 한참을 헤메이게 되죠.
모듈을 가져올 때 from - import - 를 하면
이들이 지금 쓰고 있는 소스파일에서
해당 이름에 대한 우선권을 갖습니다.
보통 프로그램 하나 만들기 위해서
여러개의 import 를 사용하므로
이름이 겹치는지 항상 확인해야 합니다.
그리고 이들이 import로 불러오는 것이
모듈(파일)인지 클래스인지, 메소드인지, 속성인지
그냥 그 문장만 봐서는 모릅니다.
일단은 이름을 보고 추론을 하는 것입니다.
아, 이것은 클래스같다. 함수같다.
메타설명이 약간 길어졌는데 어쨋든 그렇습니다.
위 코드를 실행하면 아래와 같이 키보드를 입력합니다.
aDZ
Hello my Friend
콘솔에다 출력하는게 아니라 입력을 하는 겁니다.
실행하고 1초의 시간이 있으므로
메모장 등에 커서를 옮겨서 실행할 수 있습니다.
키보드 모니터링. 구조로 보면 마우스 pynput.mouse 와도 비슷합니다.
from pynput import keyboard
def on_press(key):
try:
print(f'알파벳 \'{key.char}\' 눌림')
except AttributeError:
print(f'특수키 {key} 눌림')
def on_release(key):
print(f'키보드 {key} 풀림')
if key == keyboard.Key.esc:
# esc 키에서 풀림
return False
# Collect events until released
# pynput.mouse와 같다
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
keyboard.Listener 와 콜백방식을 사용하고 있습니다.
키는 누를 때 press 풀 때 release 두가지는
별도의 이벤트로 처리해야합니다. 마우스와 같습니다.
한번 누를 때 처리하고 뗄 때 처리하고 두번 기회가 있습니다.
클릭이란 press 와 release 두 가지를 합산한 개념입니다.
개별 키를 제어하고 싶으면
if key == keyboard.Keycode(char='키코드') 에서 콘트롤 가능합니다.
Listener 방식에서 예외처리를 합니다.
사용자 정의 예외처리 클래스를 사용합니다.
별다를 것은 없습니다.
from pynput import keyboard
class MyException(Exception):
pass
def on_press(key):
if key == keyboard.Key.esc:
raise MyException(key)
# Collect events until released
with keyboard.Listener(
on_press=on_press) as listener:
try:
listener.join()
except MyException as e:
print('{0} was pressed'.format(e.args[0]))
동기화 방식으로 키보드를 제어합니다.
마우스 컨트롤 하는 것과 구조가 거의 같네요.
동작이 press와 release 정도이므로
키보드가 마우스보다 좀더 수월해 보입니다.
키에 대한 동작을 정의하려면 if 절을 쓰면 됩니다.
keyboard.KeyCode 메소드로 어떤 키가 눌렸는지 확인이 가능합니다.
from pynput import keyboard
# The event listener will be running in this block
with keyboard.Events() as events:
for event in events:
if event.key == keyboard.Key.esc:
print(event.key)
print("프로그램 종료")
break
if event.key == keyboard.KeyCode(char='s'):
# 개별 키보드에 대응하는 동작을 정의한다(함수 등에)
print("smith", keyboard.KeyCode(char='s'))
else:
print(f'키보드 이벤트 {event}')
이 포스팅은 키보드 부분을 다루었고
마우스 자동화 부분은 아래 링크를 참조 바랍니다.
파이썬 마우스 자동화 pynput 모듈 조작하기 (tistory.com)
상세사항은 pynput에 문서화가 잘되있으니 참고합니다.
그리고 pyautogui 도 비슷한 모듈인데 약간 사용법이 다릅니다.
이 두개 모듈을 함께 사용하는 경우도 있으니
아래 포스팅도 참고하면 도움이 될 겁니다.
파이썬 | 마우스 자동 조작 하기 | GUI 조작 프로그래밍 | pyautogui 모듈 | 매크로
파이썬 | 자동 키보드 프로그래밍 | pyautogui 모듈