簡體   English   中英

檢測何時按下 Ctrl(或其他修飾鍵)的正確方法

[英]Proper way to detect when Ctrl (or other modifier key) is pressed

我想以是否按下修飾鍵 (Ctrl) 為條件進行操作。 我發現的一種解決方法是安裝一個事件過濾器並使用QApplication.queryKeyboardModifiers()來檢測何時Ctrl ,並使用QApplication.keyboardModifiers()來檢測何時釋放Ctrl

from PySide6.QtCore import Qt, Signal
from PySide6.QtWidgets import QApplication, QMainWindow

class MainWindow(QMainWindow):

    ctrl_signal = Signal(bool)

    def __init__(self):
        QMainWindow.__init__(self)
        self.installEventFilter(self)
        self.ctrl_signal.connect(self.ctrl_slot)

    def eventFilter(self, _object, e):
        if QApplication.queryKeyboardModifiers() == Qt.CTRL: # This runs twice, and only on key press (not release)
            print("Ctrl pressed")
            self.ctrl_signal.emit(True)
        elif QApplication.keyboardModifiers() == Qt.CTRL: # This runs once, but only on release
            print("Ctrl released")
            self.ctrl_signal.emit(False)
        return False

    def ctrl_slot(self, e):
        print("e: ", e)  # Do something

app = QApplication([])
window = MainWindow()
window.show()
app.exec_()

但是,我擔心這是對.queryKeyboardModifiers().keyboardModifiers()函數的意外使用,因此以后可能會導致更多麻煩。 是否有適當的方法來檢測何時單獨按下/釋放修改鍵(即沒有按下任何其他鍵)?

雖然我使用的是 PySide6,但如果有幫助,我會接受 C++ 或 PyQt 中的答案。

您當前正在做的是檢查每次事件發生時是否按下了Ctrl鍵(例如單擊、移動、調整大小等),這似乎不是您的目標,而只是檢測何時發生更改,所以您必須針對 Qt.KeyPress 或 Qt.KeyRelease 事件改進您的過濾器。 另一方面,如果您想檢測另一個子小部件何時使用事件,則您的方法將不起作用,因為它不會傳播到父小部件,而是最好將過濾器應用於 QWindow,因為鍵盤事件在它到達時到達有重點,不依賴孩子的邏輯。

from PySide6.QtCore import Qt, Signal, QObject, QEvent
from PySide6.QtWidgets import QApplication, QMainWindow


class ControlHelper(QObject):
    ctrl_signal = Signal(bool)

    def __init__(self, window):
        super().__init__(window)
        self._window = window

        self.window.installEventFilter(self)

    @property
    def window(self):
        return self._window

    def eventFilter(self, obj, event):
        if obj is self.window:
            if event.type() == QEvent.KeyPress:
                if event.key() == Qt.Key_Control:
                    self.ctrl_signal.emit(True)
            if event.type() == QEvent.KeyRelease:
                if event.key() == Qt.Key_Control:
                    self.ctrl_signal.emit(False)
        return super().eventFilter(obj, event)


class MainWindow(QMainWindow):
    ctrl_signal = Signal(bool)

    def ctrl_slot(self, e):
        print("e: ", e)


app = QApplication([])
window = MainWindow()
window.show()

helper = ControlHelper(window.windowHandle())
helper.ctrl_signal.connect(window.ctrl_slot)

app.exec_()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM