pyqt5如何连接子窗口小部件的快捷方式

时间:2017-06-28 16:48:43

标签: python python-3.x pyqt keyboard-shortcuts pyqt5

我有一个用表格(导入的表格)填充的QtableWidget。每个表单基本上都是一个包含几个按钮和一个旋转框的Qgroupbox。我选择将这些放在表格中,以便箭头键可用于在组合框之间导航。但我想通过键盘快捷键检查每个按钮,并通过某种键盘快捷键调整旋转框(也许是移位加箭头)。我的导航大部分都在工作,但我分配给按钮的快捷方式不起作用。似乎我需要一种方法将快捷方式从具有焦点的组合框“传递”到该组框内的目标小部件。调整旋转盒的第二个问题似乎是相关的,但我甚至不清楚如何设置它。

我已经为表单添加了大部分代码(使用QTCtreator生成)。我觉得快捷代码在重新翻译方法中很有意思。

单一形式的图像

表格网格的图像

class Ui_FormLoads(object):
    def setupUi(self, FormLoads):
        FormLoads.setObjectName("FormLoads")
        FormLoads.resize(88, 105)
        FormLoads.setFocusPolicy(QtCore.Qt.TabFocus)
        FormLoads.setWindowTitle("LoadChannel")
        self.gridLayout = QtWidgets.QGridLayout(FormLoads)
        self.gridLayout.setContentsMargins(8, 8, 8, 8)
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QtWidgets.QGroupBox(FormLoads)
        font = QtGui.QFont()
        font.setPointSize(10)
        self.groupBox.setFont(font)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setContentsMargins(8, 8, 8, 8)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.pushStop = QtWidgets.QPushButton(self.groupBox)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushStop.sizePolicy().hasHeightForWidth())
        self.pushStop.setSizePolicy(sizePolicy)
        self.pushStop.setMinimumSize(QtCore.QSize(30, 0))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.pushStop.setFont(font)
        self.pushStop.setText("Stop")
        self.pushStop.setCheckable(True)
        self.pushStop.setObjectName("pushStop")
        self.gridLayout_2.addWidget(self.pushStop, 1, 0, 1, 1)
        self.pushReload = QtWidgets.QPushButton(self.groupBox)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushReload.sizePolicy().hasHeightForWidth())
        self.pushReload.setSizePolicy(sizePolicy)
        self.pushReload.setMinimumSize(QtCore.QSize(30, 0))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.pushReload.setFont(font)
        self.pushReload.setText("Load")
        self.pushReload.setCheckable(True)
        self.pushReload.setObjectName("pushReload")
        self.gridLayout_2.addWidget(self.pushReload, 1, 1, 1, 1)
        self.spinBox = QtWidgets.QSpinBox(self.groupBox)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.spinBox.sizePolicy().hasHeightForWidth())
        self.spinBox.setSizePolicy(sizePolicy)
        self.spinBox.setMinimumSize(QtCore.QSize(51, 0))
        font = QtGui.QFont()
        font.setPointSize(13)
        self.spinBox.setFont(font)
        self.spinBox.setMinimum(-20)
        self.spinBox.setMaximum(12)
        self.spinBox.setObjectName("spinBox")
        self.gridLayout_2.addWidget(self.spinBox, 0, 0, 1, 2)
        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)

        self.retranslateUi(FormLoads)
        QtCore.QMetaObject.connectSlotsByName(FormLoads)

    def retranslateUi(self, FormLoads):
        _translate = QtCore.QCoreApplication.translate
        self.groupBox.setTitle(_translate("FormLoads", "GroupBox"))
        self.pushStop.setShortcut(_translate("FormLoads", "S"))
        self.pushReload.setShortcut(_translate("FormLoads", "L"))

1 个答案:

答案 0 :(得分:1)

好吧,我想出了如何做到这一点。 [btw formLoad是我在迭代填充表格时用于表单的变量名称。 actionStop是我用于此特定快捷方式的变量名称。]

self.formLoad.actionStop = QtWidgets.QShortcut(QtGui.QKeySequence("S"), self.formLoad)
self.formLoad.actionStop.activated.connect(self.formLoad.ui.pushStop.click)
self.formLoad.actionStop.setContext(QtCore.Qt.WidgetWithChildrenShortcut)

A)首先是了解范围和重点。我最终将最高级的小部件(用于表单)设置为strongfocus,除了旋转框之外的其他所有内容都设置为nofocus。将纺纱箱设定为轮转,使其可以轮式或打字。焦点设置可以在QtCreator / Designer中设置,这意味着您必须在主py文件中添加更少的内容。保持关键按钮保持按键命令不会将焦点转移到单个按钮,我怀疑在Mac上可能会出现问题,具体取决于您是否将键盘快捷键设置为" all"在系统偏好中。然后,将context属性设置为' WidgetWithChildrenShortcut'允许keycommand从顶部窗口小部件向下过滤到按钮。 [顺便说一句,似乎没有办法使用你可以在QtCreator中设置的快捷方式来定义上下文,所以我明确地定义了快捷方式。]当我创建actionStop快捷方式时,你可以看到我将它分配给formLoad作为它的父母。这将指定为strongfocus设置的窗口小部件的快捷方式。

self.formLoad.actionIncrement = QtWidgets.QShortcut(QtGui.QKeySequence("Alt+Up"), self.formLoad)
self.formLoad.actionIncrement.activated.connect(self.formLoad.ui.spinBox.stepUp)
self.formLoad.actionIncrement.setContext(QtCore.Qt.WidgetWithChildrenShortcut)
self.formLoad.actionDecrement = QtWidgets.QShortcut(QtGui.QKeySequence("Alt+Down"), self.formLoad)
self.formLoad.actionDecrement.activated.connect(self.formLoad.ui.spinBox.stepDown)
self.formLoad.actionDecrement.setContext(QtCore.Qt.WidgetWithChildrenShortcut)

B)其次,我必须弄清楚哪些属性(及其名称)可以被触发"通过捷径。这些在QPushButton或QSpinBox的主要QT页面上没有清楚记录。我找到了"点击"在一些示例代码中联机并在QAbstractSpinBox的QT文档中找到了向上和向下按钮属性。 '升压'和' stepDown'相当于单击旋转框的向上或向下按钮。在这种情况下,我使用Alt修饰键和向上和向下箭头。 Qt文档中的某个地方是关键命令列表及其字符串标题(" Alt + Up"等)。

    self.formLoad.actionZero = QtWidgets.QShortcut(QtGui.QKeySequence("0"), self.formLoad)
    self.formLoad.actionZero.setContext(QtCore.Qt.WidgetWithChildrenShortcut)
    self.formLoad.actionZero.activated.connect(functools.partial(self.spinboxset, 0, self.formLoad.ui.spinBox))

@QtCore.pyqtSlot()
def spinboxset(self, key, spInBox):
    spInBox.setValue(key)

C)最后,我决定实现一些直接将特定值加载到spinbox中的关键命令。这比较棘手,因为你不能使用' setValue'直接从activated.connect行运行。我在lambda上尝试了一些变体,但是导入functools并使用partial和一个单独的函数是有效的。 partial传递的最后一个元素是spinbox,它是正在填充的单元格的子窗口小部件。这样,该方法知道将值应用于哪个spinbox。如果不发送,它将始终将值应用于最后一个formLoad.spinBox'已使用该名称定义的。传递的第二个元素(称为键)是值。这允许一个方法(spinboxset)用于多个键命令。例如,可以为" 5"设置另一个。

self.formLoad.actionFive = QtWidgets.QShortcut(QtGui.QKeySequence("5"), self.formLoad)
self.formLoad.actionFive.setContext(QtCore.Qt.WidgetWithChildrenShortcut)
self.formLoad.actionFive.activated.connect(functools.partial(self.spinboxset, 5, self.formLoad.ui.spinBox))

现在,如果有人可以告诉我如何在单元格之间复制和粘贴单元格的所有设置,我将会设置...