没有焦点的 KeyPressEvent

KeyPressEvent without Focus

我正在编写一个简单的 GUI,它将在特定点打开 opencv window。这个 window 有一些非常基本的 keyEvents 来控制它。我想通过一些功能来推进这一点。因为我的 QtGui 是我的控制器,所以我认为使用 KeyPressedEvent 是一个好方法。我的问题是,如果我在 opencv window.

上处于活动状态,我将无法触发 KeyEvent

如果我的 Gui 没有焦点,我该如何触发 KeyEvent?

我真的需要使用 GrabKeyboard 吗?

以下代码重现了我的问题:

import sys
from PyQt5.QtWidgets import (QApplication, QWidget)
from PyQt5.Qt import Qt
import cv2


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.first = True

    def openselect(self):
        im = cv2.imread(str('.\images\Steine\0a5c8e512e.jpg'))
        self.r = cv2.selectROI("Image", im)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space and self.first:
            self.openselect()
            self.first = False
        print('Key Pressed!')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()

    win.show()
    sys.exit(app.exec_())

keyPressEvent 方法仅在小部件具有焦点时调用,因此如果焦点具有另一个应用程序则不会通知它,因此如果要检测键盘事件则必须处理 OS 库,但在 python 中,它们已经存在将这些更改报告为 pyinput(python -m pip install pyinput):

的库
import sys

from PyQt5 import QtCore, QtWidgets

from pynput.keyboard import Key, Listener, KeyCode


class KeyMonitor(QtCore.QObject):
    keyPressed = QtCore.pyqtSignal(KeyCode)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.listener = Listener(on_release=self.on_release)

    def on_release(self, key):
        self.keyPressed.emit(key)

    def stop_monitoring(self):
        self.listener.stop()

    def start_monitoring(self):
        self.listener.start()


class MainWindow(QtWidgets.QWidget):
    pass


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    monitor = KeyMonitor()
    monitor.keyPressed.connect(print)
    monitor.start_monitoring()

    window = MainWindow()
    window.show()

    sys.exit(app.exec_())