파이썬으로 'Hotstring' 기능을 구현해보겠습니다. 여기서 Hotstring 기능이란, 예를 들어 'hw'만 입력하고 스페이스를 치면, 'Hello, world!'와 같이 완성된 단어나 문장을 만드는 방법이라고 정의하겠습니다. 하나의 키, 혹은 동시에 두 개 이상의 키를 눌러 특정 기능을 수행하는 'Hotkey' 기능과 차이점을 명확히 하기 위함입니다.
기본 코드
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
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()
Hotstring 기능을 구현하기 위해 'pynput' 패키지를 사용하겠습니다. 어떤 키보드 키가 입력되었는지 확인할 수 있는 코드입니다. 위 코드는 여기에서 가져왔습니다.
눌린 키 저장하기
일단 print문은 지저분하니 지우고.. 'hw'입력을 저장하기 위한 빈 리스트를 'keys'라고 정의하겠습니다. on_press 함수를 수정해서 키가 눌릴 때마다 그 눌린 키를 keys에 key.char를 append 하겠습니다. keys가 계속 append 되면 크기가 너무 커지니, 일정 크기 이상이면 맨 앞자리를 지우도록 하겠습니다.
벌써부터 분기점이 생기는데 space를 문자로 볼 것인가 입니다. 저는 space를 두 번 이상 쳤을 때도 특정 문자가 나오도록 만들고 싶기 때문에, space도 문자로 보겠습니다. space는 key.char 속성이 없어 AttributeError가 발생하기 때문에 keys.append()를 except 이후에도 만들어줘야 합니다.
keys = []
def on_press(key):
try:
keys.append(key.char)
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
except AttributeError:
if key == keyboard.Key.space: # space = ' '
keys.append(' ')
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
Typer 함수 만들기
컴퓨터 키보드를 직접 쳐주는 함수를 먼저 만들어봅시다. 키보드 조작을 위해 아래와 같이 controller class를 호출하여 my_key instance를 선언해주겠습니다. 문제는 my_key.press('str')를 실행시키면 str을 직접 타이핑할 순 있지만, 단 하나의 글자만 타이핑이 가능합니다. 따라서, 연속된 글자들, 즉 문장을 타이핑하기 위해서 새로운 typer 함수를 만들어보겠습니다.
from pynput import keyboard
my_key = keyboard.Controller()
# 하나의 글자는 문제가 없지만
my_key = keyboard.Controller()
my_key.press('H')
# 두 개 이상의 글자는 ValueError 발생
my_key = keyboard.Controller()
my_key.press('Hello, world!')
방법은 단순하게, 입력된 문장을 글자 하나씩 쪼개서 직접 타이핑 하겠습니다.
def typer(sentence):
for i in range(len(sentence)):
my_key.press(sentence[i])
return
typer('Hello, world!')
Helo, world! # 완전히 타이핑이 안된다!
결과는 'l' 하나를 타이핑하지 못했습니다. 키보드를 누르기만 해서 이런 결과가 생긴 것이니, 키보드를 떼는 일도 추가해줍시다. (우리는 키보드를 누르고 뗍니다.)
def typer(sentence):
for i in range(len(sentence)):
my_key.press(sentence[i])
my_key.release(sentence[i])
return
typer('Hello, world!')
Hello, world! # 제대로 출력이 된다!
Hotstring 함수 만들기
자 이제 keys에 저장된 글자들과 typer 함수를 이용해 hotstring 기능을 구현해봅시다.
일단 저는 space가 눌렸을 때, 직전에 눌린 키가 'h', 'w' 면 'Hello, world!'를 출력하고 싶습니다. 따라서 특정 글자와 문장을 짝지어주는 함수를 만들어줍니다.
def hotstring(letters, sentence):
key_word = ''.join(keys[-len(letters):])
if key_word == letters:
typer(sentence)
return
그리고 'hw '와 'Hello, world!'를 이어주는 함수를 또 하나 만들어줍니다.
def hotstrings():
hotstring('hw ', 'Hello world!')
return
위 모든 함수들을 소스 코드에 집어넣고 space가 눌렸을 때, hotstrings 함수가 작동되도록 keys에 space가 append 된 직후에 위치시킵니다.
def on_press(key):
try:
keys.append(key.char)
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
except AttributeError:
if key == keyboard.Key.space: # space = ' '
keys.append(' ')
hotstrings() # hotstrings
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
위 소스 코드를 작동시킨 후 'hw '를 입력시키면, 'hw Hello world!'가 입력됩니다. 맞습니다. backspace를 빼먹었군요... 키워드의 길이만큼 backspace를 입력하는 함수를 만들어줍시다.
Backspace 입력 함수 만들기
아래와 같이 입력된 변수 num만큼 backspace를 입력하는 함수를 만듭니다.
def backspace(num):
for i in range(num):
my_key.press(keyboard.Key.backspace)
my_key.release(keyboard.Key.backspace)
return
위 함수를 hotstring 함수에서 letters의 길이로 입력값을 넣어줍니다.
def hotstring(letters, sentence):
key_word = ''.join(keys[-len(letters):])
if key_word == letters:
backspace(len(letters))
typer(sentence)
return
완성된 소스 코드
from pynput import keyboard
keys = []
my_key = keyboard.Controller()
def typer(sentence):
for i in range(len(sentence)):
my_key.press(sentence[i])
my_key.release(sentence[i])
return
def backspace(num):
for i in range(num):
my_key.press(keyboard.Key.backspace)
my_key.release(keyboard.Key.backspace)
return
def hotstring(letters, sentence):
key_word = ''.join(keys[-len(letters):])
if key_word == letters:
backspace(len(letters))
typer(sentence)
return
def hotstrings():
hotstring('hw ', 'Hello world!')
return
def on_press(key):
try:
keys.append(key.char)
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
except AttributeError:
if key == keyboard.Key.space: # space = ' '
keys.append(' ')
hotstrings() # hotstrings
if len(keys) >= 5: # to prevent too many elements in keys
del keys[0:len(keys)-5]
print(keys) # for monitoring
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
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()
자 이제 완성된 소스 코드를 돌리고 'hw '를 입력해보면 'Hello, world!'를 정상적으로 타이핑하는 걸 확인할 수 있습니다. 원하는 문장을 hotstring 함수를 이용해 hotstrings에 추가하여 사용하면 됩니다.
다음은 위 코드를 더 수정하여 좀 더 많은 기능을 추가해보도록 하겠습니다.
'Computer > Python' 카테고리의 다른 글
정규 표현식 (Regular expression) 1 (1) | 2023.12.03 |
---|---|
파이썬으로 Hotstring 기능 구현하기 2 (0) | 2022.09.03 |
왜 파이썬인가? (0) | 2022.07.10 |
댓글