Qt菜单快捷键优先处理子窗口的按键事件

2 投票
1 回答
1761 浏览
提问于 2025-04-17 07:05

我有一个主窗口,在这个窗口里我设置了常见的编辑操作,比如剪切、复制和粘贴。这些操作的菜单项都链接到了一个叫QTextEdit的控件,这个控件是主窗口的一个子控件。

主窗口还有另一个子控件(在分割条的另一边),这个控件显示的是一个表格视图(TableView)。这个控件的焦点策略是点击就能获得焦点,并且有一个处理按键事件的功能。当这个控件获得焦点时,它的按键事件处理方法会拦截所有的按键输入(我知道这一点,因为它会在控制台上打印出来),除了Ctrl+C、Ctrl+V和其他一些分配给编辑或文件菜单的按键组合。这些按键会被发送到菜单,并在没有焦点的QTextEdit中生效。

我想在表格视图中捕捉到Ctrl+C的操作,以便复制表格中选中的值,但这个按键组合根本没有被捕捉到。

我该怎么做才能让Ctrl+C的操作被当前有焦点的控件识别到呢?

1 个回答

1

当你创建编辑操作时,给它们一个 WidgetShortcut 的上下文,并把它们 添加 到你想要关联的控件上:

copyAction.setShortcutContext(Qt.WidgetShortcut)
editor.addAction(copyAction)

请注意,以这种方式配置的操作快捷键不会覆盖关联控件本身已有的快捷键。

补充说明

这里有一个简单的示例。注意,当 文本编辑框 获得键盘焦点时,按 'Ctrl+P' 会触发相应的处理程序,但 'Ctrl+C' 不会,因为它是一个内置的快捷键。当 表格 获得键盘焦点时,'Ctrl+C' 会正常复制选中的项目,但 'Ctrl+P' 则不会有任何反应。

from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        widget = QtGui.QWidget(self)
        self.setCentralWidget(widget)
        layout = QtGui.QVBoxLayout(widget)
        self.edit = QtGui.QTextEdit(self)
        self.edit.setText('text')
        self.table = Table(self)
        layout.addWidget(self.edit)
        layout.addWidget(self.table)
        menu = self.menuBar().addMenu('&File')
        def add_action(text, shortcut):
            action = menu.addAction(text)
            action.setShortcut(shortcut)
            action.triggered.connect(self.handleAction)
            action.setShortcutContext(QtCore.Qt.WidgetShortcut)
            self.edit.addAction(action)
        add_action('&Copy', 'Ctrl+C')
        add_action('&Print', 'Ctrl+P')

    def handleAction(self):
        print ('Action!')

class Table(QtGui.QTableWidget):
    def __init__(self, parent):
        QtGui.QTableWidget.__init__(self, parent)
        self.setRowCount(4)
        self.setColumnCount(2)
        self.setItem(0, 0, QtGui.QTableWidgetItem('item'))

    def keyPressEvent(self, event):
        print ('keyPressEvent: %s' % event.key())
        QtGui.QTableWidget.keyPressEvent(self, event)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

撰写回答