問題描述
如何在 PyQT5 中實現(xiàn)關(guān)鍵監(jiān)聽器?即使應(yīng)用在后臺,我也想檢測按鍵.
How can I implement a key listener in PyQT5? I want to detect keypresses even when the app is in background.
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 只有在其頂層窗口有鍵盤焦點時才能訪問鍵盤事件.如果窗口被最小化或另一個窗口獲得焦點,您將不會收到鍵盤事件.
Qt can access keyboard events only if any of its top level window has keyboard focus. If the window is minimized or another window takes focus, you will not receive keyboard events.
唯一的解決方案是使用外部庫,但它們有局限性.
The only solution is to use an external library, but they have limitations.
keyboard 模塊似乎不支持 macOS,而 pyinput 可以,但需要該操作系統(tǒng)的 root 訪問權(quán)限.我不知道有任何其他方法可以不受限制地支持所有三個平臺.
The keyboard module does not seem to support macOS, while pyinput does, but requires root access for that OS. I don't know of any other ways that support all three platforms without limitations.
在任何情況下,您都不應(yīng)該依賴于對當前按鍵的定時檢查,因為您最終肯定會錯過一些事件.
雖然通常會使用一個單獨的線程來實現(xiàn)事件偵聽器(通常是阻塞的),但幸運的是在這兩種情況下都有非阻塞系統(tǒng)來調(diào)用回調(diào)函數(shù)(因此您實際上不需要單獨的線程).
In any case, you should not rely on timed checking of the currently pressed keys, because you'll certainly end up missing some events.
While normally one would use a separate thread that implements the event listener (which are normally blocking), luckily in both cases there are non blocking systems to call callback functions (so you don't actually need a separate thread).
以下是使用 keyboard
模塊的基本示例:
The following is a basic example using the keyboard
module:
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)
這篇關(guān)于在 PyQt5 中檢測外部鍵盤事件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!