如果在 PyQt5 中按下了不必要的键(包括或排除用户定义的预定义键),如何避免处理?

How to avoid the processing, if an unnecessary key is pressed (include or exclude user-defined, pre-defined keyss) in PyQt5?

如果按下了不必要的键,如何避免处理?例如,在我的代码中,我在 keyPressEvent 中使用 Right ArrowLeft Arrowkey 从一个标签移动到另一个标签。我分配键 F5, Alt+ Actrl+alt+p 作为标签的快捷方式。默认打印第一个标签 "Accounts" 被选中。现在,如果我按任意键(如 u、v、a、alt、ctrl 等),我会得到结果 "Accounts is selected" 作为很多时候,我按下了其他键。如果我按 F5,Label Manufacture 是 selected/print,但现在我按任意键然后我得到一条打印消息“Manufacture is selected

我的意图是,如果我按向右、向左箭头键或分配的Qkeysequence键,那么只有我得到响应(打印selected Item),如果我按任何其他键,避免处理并且我不想显示任何内容。 (这​​里QKeySequence的key是动态的,不是常量,因人而异)

import sys

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
  
class Dynamic_Widgets(QWidget):

    def __init__(self):
        super(). __init__()
        self.setWindowTitle("Dynamic Widget")
        self.vbox1 = QVBoxLayout()
        self.vbox2 = QVBoxLayout()
        self.hbox = QHBoxLayout()
        self.hbox.addLayout(self.vbox1),self.hbox.addLayout(self.vbox2)
        self.hbox.addSpacing(5),self.setLayout(self.hbox)

        self.lbl_1 = QLabel("Accounts")
        self.lbl_2 = QLabel("Inventory")
        self.lbl_3 = QLabel("Manufacture")

        self.lbl_1_sc = QLabel("Alt+A")
        self.lbl_2_sc = QLabel("alt+ctrl+P")
        self.lbl_3_sc = QLabel("F5")

        self.store_sc = {}
        self.item_list = []
        self.item_list_sc = []

        self.vbox1.addWidget(self.lbl_1)
        self.vbox1.addWidget(self.lbl_2)
        self.vbox1.addWidget(self.lbl_3)
        self.item_list.append(self.lbl_1.text())
        self.item_list.append(self.lbl_2.text())
        self.item_list.append(self.lbl_3.text())

        self.vbox2.addWidget(self.lbl_1_sc)
        self.vbox2.addWidget(self.lbl_2_sc)
        self.vbox2.addWidget(self.lbl_3_sc)

        self.item_list_sc.append(self.lbl_1_sc.text())
        self.item_list_sc.append(self.lbl_2_sc.text())
        self.item_list_sc.append(self.lbl_3_sc.text())

        self.active_part = 1
        self.first_option = 0
        self.first_option_result = ""
        self.first_option_result = self.item_list[self.first_option]
        self.func_final_result()

        for count,item in enumerate(self.item_list):
            self.store_sc[count] = QShortcut(QKeySequence(f'{(self.item_list_sc[count])}'),self)
            self.store_sc[count].activated.connect(self.result)

    def result(self):
        shortcut = self.sender()
        sc_key = QKeySequence(shortcut.key()).toString()
        sc_key_index = self.item_list_sc.index(sc_key)
        self.first_option = sc_key_index
        self.first_option_result = self.item_list[sc_key_index]
        self.func_final_result()

    def keyPressEvent(self, event):
        if self.active_part == 1:
            if (event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter) and self.first_option == 0:
                self.first_option = 0
            if event.key() == Qt.Key_Right and  self.first_option < len(self.item_list)-1:
                self.first_option = self.first_option + 1
            if event.key() == Qt.Key_Left and self.first_option > 0:
                self.first_option = self.first_option - 1
            if self.first_option != -1:
                self.first_option_result = self.item_list[self.first_option]
                self.func_final_result()

    def func_final_result(self):
        print(self.first_option_result, "is selected")

def main():
    app = QApplication(sys.argv)
    ex = Dynamic_Widgets()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

如果您只想处理特定的键,那么您要么检查事件键是否在“已处理”键列表中并继续处理,要么 忽略如果不是,则为事件。

请注意,您必须不是比较密钥的字符串表示,而是它的 QKeySequence。

class Dynamic_Widgets(QWidget):
    def __init__(self):
        # ...
        self.item_list_sc.append(QKeySequence(self.lbl_1_sc.text()))
        self.item_list_sc.append(QKeySequence(self.lbl_2_sc.text()))
        self.item_list_sc.append(QKeySequence(self.lbl_3_sc.text()))

        self.key_indexes = {}
        for i, key in enumerate(self.item_list_sc):
            shortcut = self.store_sc[i] = QShortcut(key, self)
            shortcut.activated.connect(self.result)
            self.key_indexes[key] = i

    def result(self):
        shortcut = self.sender()
        sc_key_index = self.key_indexes.get(shortcut.key())
        if sc_key_index is None:
            return
        self.first_option = sc_key_index
        self.first_option_result = self.item_list[sc_key_index]
        self.func_final_result()

    def keyPressEvent(self, event):
        key = event.key()
        if key not in (Qt.Key_Return, Qt.Key_Enter, Qt.Key_Left, Qt.Key_Right):
            return
        if self.active_part == 1:
            if key in (Qt.Key_Return, Qt.Key_Enter):
                self.first_option = 0
            elif (key == Qt.Key_Right 
                and self.first_option < len(self.item_list) - 1):
                    self.first_option += 1
            elif key == Qt.Key_Left and self.first_option > 0:
                self.first_option -= 1

            if self.first_option >= 0:
                self.first_option_result = self.item_list[self.first_option]
                self.func_final_result()

或者,使用始终检查 if/elif/else 块,并最终根据其他条件处理密钥,否则 return因为到那时还没有找到关键匹配:

    def keyPressEvent(self, event):
        if self.active_part == 1:
            key = event.key()
            if key in (Qt.Key_Return, Qt.Key_Enter):
                self.first_option = 0
            elif key == Qt.Key_Right:
                if self.first_option < len(self.item_list) - 1:
                    self.first_option += 1
            elif key == Qt.Key_Left:
                if self.first_option > 0:
                    self.first_option -= 1
            else:
                return

            if self.first_option >= 0:
                self.first_option_result = self.item_list[self.first_option]
                self.func_final_result()

注意:在这种情况下,您必须始终使用 QGridLayout,否则项目在某些情况下可能无法正确对齐;最后,考虑 QFormLayout。此外,避免将多个函数调用放在一行中,这绝对没有任何好处,只会使您的代码变得笨重且难以阅读(因此难以调试)。