在 PyQt5 中检测外部键盘事件
Detect external keyboard events in PyQt5
如何在 PyQT5 中实现按键侦听器?即使应用程序处于后台,我也想检测按键。
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import sys
class Window(QWidget):
...
def keyPressEvent(self, e): # doesnt work when app is in background
if e.key() == Qt.Key_F3:
print(1)
elif e.key() == Qt.Key_F4:
print(0)
...
App = QApplication(sys.argv)
App.setStyle('Fusion')
window = Window()
sys.exit(App.exec())
仅当 Qt 的任何顶层 window 具有键盘焦点时,它才能访问键盘事件。如果 window 被最小化或另一个 window 获得焦点,您将不会收到键盘事件。
唯一的解决办法是使用外部库,但它们有局限性。
keyboard module does not seem to support macOS, while pyinput 可以,但 OS 需要根访问权限。我不知道有任何其他方式可以无限制地支持所有三个平台。
无论如何,您不应该依赖于对当前按下的键的定时检查,因为您最终肯定会错过一些事件。
虽然通常人们会使用一个单独的线程来实现事件监听器(通常是阻塞的),幸运的是在这两种情况下都有非阻塞系统来调用回调函数(所以你实际上不需要一个单独的线程)。
以下是使用 keyboard
模块的基本示例:
from PyQt5 import QtCore, QtWidgets
import keyboard
class KeyGrabber(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.button = QtWidgets.QPushButton('start')
layout.addWidget(self.button)
self.button.setCheckable(True)
self.button.toggled.connect(self.setGrabbing)
def keyboardEventReceived(self, event):
if event.event_type == 'down':
if event.name == 'f3':
print('F3 pressed')
elif event.name == 'f4':
print('F4 pressed')
def setGrabbing(self, enable):
if enable:
self.button.setText('stop')
# on_press returns a hook that can be used to "disconnect" the callback
# function later, if required
self.hook = keyboard.on_press(self.keyboardEventReceived)
self.showMinimized()
else:
self.button.setText('start')
keyboard.unhook(self.hook)
如何在 PyQT5 中实现按键侦听器?即使应用程序处于后台,我也想检测按键。
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import sys
class Window(QWidget):
...
def keyPressEvent(self, e): # doesnt work when app is in background
if e.key() == Qt.Key_F3:
print(1)
elif e.key() == Qt.Key_F4:
print(0)
...
App = QApplication(sys.argv)
App.setStyle('Fusion')
window = Window()
sys.exit(App.exec())
仅当 Qt 的任何顶层 window 具有键盘焦点时,它才能访问键盘事件。如果 window 被最小化或另一个 window 获得焦点,您将不会收到键盘事件。
唯一的解决办法是使用外部库,但它们有局限性。
keyboard module does not seem to support macOS, while pyinput 可以,但 OS 需要根访问权限。我不知道有任何其他方式可以无限制地支持所有三个平台。
无论如何,您不应该依赖于对当前按下的键的定时检查,因为您最终肯定会错过一些事件。
虽然通常人们会使用一个单独的线程来实现事件监听器(通常是阻塞的),幸运的是在这两种情况下都有非阻塞系统来调用回调函数(所以你实际上不需要一个单独的线程)。
以下是使用 keyboard
模块的基本示例:
from PyQt5 import QtCore, QtWidgets
import keyboard
class KeyGrabber(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.button = QtWidgets.QPushButton('start')
layout.addWidget(self.button)
self.button.setCheckable(True)
self.button.toggled.connect(self.setGrabbing)
def keyboardEventReceived(self, event):
if event.event_type == 'down':
if event.name == 'f3':
print('F3 pressed')
elif event.name == 'f4':
print('F4 pressed')
def setGrabbing(self, enable):
if enable:
self.button.setText('stop')
# on_press returns a hook that can be used to "disconnect" the callback
# function later, if required
self.hook = keyboard.on_press(self.keyboardEventReceived)
self.showMinimized()
else:
self.button.setText('start')
keyboard.unhook(self.hook)