키보드로부터 입력을 받아서 인터럽트를 발생시키고 싶었다.
키보드 인풋을 받아오는 방법은 검색을 해보니 다양한게 나왔는데
일단 PyQt에서 자체적으로 지원하는 keyboad event 핸들러를 사용하는 방법이 있었다.
아래는 PyQt 가 제공하는 키보드 이벤트 핸들러 사용한 예시케이스이다.
1.PyQt가 제공하는 키보드 이벤트 핸들러 사용
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Test")
self.setGeometry(1000, 200, 300, 300)
def keyPressEvent(self, e): #키가 눌러졌을 때 실행됨
if e.key() == Qt.Key_Escape:
print("esc pressed")
elif e.key() == Qt.Key_A:
print("A is pressed)")
else:
print((e.key()))
def keyReleaseEvent(self,e): #키를 누른상태에서 뗏을 때 실행됨
print("kye is pressed:")
print(e.key())
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
코드 구현방법은 간단하다.
이름에서 유추가 가능할 텐데
키보드에 아무거나 키를 누르면 KeyPressEvent 메소드가 실행된다.
그리고 누르고 있던 키를 떼면 KeyReleaseEvent 메소드가 실행된다.
이 때 실행되는 메소드에 argument로 해당 키의 정보가 전달되는 형태이다.
한가지 유의할 점은 위 이벤트핸들러에서 받아오는 e 값은 아스키코드 값을 받아오는데
특수키인 shift, backspace, space, enter 키등등은 아스키코드 범위를 벗어나는 매우 큰 숫자가 나오더라.
특수키에 대한 처리 어떻게 해줄지 정의 필요 할 듯.(그 방법은 일단 나중에 알아보고. 우선 여기서는 패스)
2.pynput 라이브러리 사용
근데 여기서 문제가 있었다.
내가 하고싶은게 뭐였냐면
PyQt로 만들어진 SW를 실행시킨 후, 이 SW를 활성화시키지 않은 상태에서 키보드 인풋을 받고 싶었다.
(예를 들어서 PyQt GUI SW를 실행시킨 상태에서, 이 sw는 작업표시줄에 최소화 시켜놓고 다른 프로그램을 활성화시킨 상태)
이 상태에서는 위의 이벤트 핸들러가 동작을 하지 않았다.
앞에서 살펴봤던 키보드 핸들러는 PyQt SW가 컴퓨터상에서 활성화 돼있을 때만 동작하고 있었다.
그래서 PyQt GUI SW가 비활성화 상태에서도 키보드 이벤트를 받을 수 있는 방법을 찾게되었고..
pynput 이라는 라이브러리를 알게되었다.
기본 라이브러리가 아니므로 pip install pynput 으로 설치를 해서 사용해야한다.
일단 기본 사용 형태를 보자.
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
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
위 코드에서 with keyboard.Listner 라는 키워드가 정확히 뭐하는 키워드인지는 공부가 더 필요하다.
위의 코드만 놓고보면 while 루프 같은게 없으니까 SW 실행하면 그냥 꺼져야될 거 같은데
정확히 어떻게 돌아가고 있는진 모르겠는데 위 코드를 실행시키면 SW가 게속 돌면서
키보드 누르면 등록된 on_press 함수가 실행되고 ,키보드 눌렀다 떼면 on_release 함수가 실행된다.
이게 기초적인 pynput 라이브러리를 사용하는 예시이다.
이 SW의 경우 PyQt의 키보드이벤트리스너와 달리 파이썬 SW가 비활성화되어있어도 동작을 하더라.
다음으로, 이 pynput 라이브러리랑 PyQt를 같이 쓰는 예시를 알아보자.
3.pynput 라이브러리를 PyQt랑 같이 사용하기
2번에서 살펴본 것 처럼 코드를 입력하면..
listener.join() 을 호출하고나면 어딘가 루프에 빠지는거 같다.
그래서 저 뒤에 있는 코드 실행이 안된다.
그래서 PyQt랑 같이 쓰려고하는데 쓸 수가 없다.
내가 찾은 방법이 과연 최선의 방법인지 의문인데 내가 찾은 방법은..
PyQt 안에서 쓰레드를 하나 추가로 만들고
이 쓰레드 안에서 pynput listner를 등록해서 사용하는 방식이다.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QThread
from pynput import keyboard
class MyThread(QThread):
cnt=0
running= False
def __init__(self):
super().__init__()
def on_press(self,key):
try:
print(f'알파벳 \'{key.char}\' 눌림')
except AttributeError:
print(f'특수키 {key} 눌림')
def on_release(self,key):
print(f'키보드 {key} 풀림')
if key == keyboard.Key.esc:
# esc 키에서 풀림
return False
def run(self):
with keyboard.Listener(on_press=self.on_press, on_release=self.on_release) as listener:
listener.join()
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Test")
self.setGeometry(1000, 200, 300, 300)
self.Thread1 = MyThread()
self.Thread1.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
'프로그래밍 관련 > PyQt' 카테고리의 다른 글
PyQt - TreeWidget (0) | 2021.10.21 |
---|---|
PyQt. Qt Designer 개요.사용방법 (1) | 2021.10.19 |
PyQt(4) 쓰레드 사용하기 (0) | 2021.09.14 |
PyQt(3) 버튼 이벤트 만들기 (0) | 2021.09.13 |
PyQt(2) 타이머 인터럽트 만들기 (0) | 2021.09.13 |