【问题标题】:pyqt5 How to connect shortcut to child widgetpyqt5 如何将快捷方式连接到子小部件
【发布时间】:2017-06-28 16:48:42
【问题描述】:

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

我附上了表单的大部分代码(使用 QTCtreator 生成)。有趣的是,快捷方式代码在 retranslate 方法中。

单一形式的图像

表格网格的图像

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"))

【问题讨论】:

  • 为什么要在 translate 方法中使用这个?
  • 我不一定要在 translate 方法中使用它,但这就是 QtCreator 自动放置它的地方。我很好奇这是一个错误还是什么?
  • 好的,spinbox呢,什么意思?
  • 我需要能够通过键盘命令向上或向下增加旋转框。我相信可以使用带有箭头键的修饰键来完成此操作。或者 + & - 键可以工作。这个想法是,用户可以使用箭头键在组框之间导航,但可以通过击键快速更改按钮和旋转框设置,而不是使用鼠标进行任何操作。我什至还没有尝试设置 spinbox 键命令设置,因为我不确定如何解释各种代码,我已经看到了如何做的提示。我希望在这里得到一些帮助。

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


【解决方案1】:

好吧,我想出了如何做到这一点。 [顺便说一句,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 并将除了 spinbox 之外的所有其他内容设置为 nofocus。 spinbox 设置为 wheelfocus,允许对其进行轮式或键入。可以在 QtCreator/Designer 中设置焦点设置,这意味着您必须在主 py 文件中添加更少的内容。将焦点从按钮上移开可以防止按键命令将焦点转移到单个按钮上,我怀疑这在 Mac 上可能会出现问题,具体取决于您是否在系统偏好设置中将键盘快捷键设置为“全部”。然后,将上下文属性设置为“WidgetWithChildrenShortcut”允许键命令从顶部小部件向下过滤到按钮。 [顺便说一句,似乎没有一种方法可以使用您可以在 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 页面上没有明确记录。我在网上的一些示例代码中找到了“click”属性,并且在 QAbstractSpinBox 的 QT 文档中找到了向上和向下按钮属性。 'stepUp' 和 '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) 最后,我决定实现一些直接将特定值加载到旋转框中的键命令。这比较棘手,因为您不能直接从 activate.connect 行中使用“setValue”函数。我尝试了 lambda 的一些变体,但导入 functools 并使用带有单独函数的部分是有效的。 partial 传递的最后一个元素是 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))

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-17
    • 2018-05-25
    • 2022-08-14
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多