user405
user405

Reputation: 579

Qt menu shortcuts preempt child widget KeyPressEvents

I have a main window in which I establish the standard Edit > Cut/Copy/Paste actions, with the menu actions linked to the relevant slots of a QTextEdit which is a child of the main window.

The main window has a different child (on the other side of a splitter) which displays a TableView. This widget has focus policy of click to focus and a KeyPressEvent handler. When this child has the focus, its KeyPressEvent method intercepts all keystroke events (I know because it prints them out on the console) EXCEPT ctl-c, ctl-v, and any other key sequences that are assigned to the edit or file menu actions. Those keystrokes go to the menu and take effect within the QTextEdit which does not have the focus.

I want to be able to catch ^c within the table view to copy the value of the table selection, but the key sequence never gets there.

What can I do to make the ^c action visible to the widget that has the focus?

Upvotes: 2

Views: 1781

Answers (1)

ekhumoro
ekhumoro

Reputation: 120578

When the edit actions are created, give them a WidgetShortcut context and add them to the widget(s) they are to be associated with:

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

Note that the shortcuts of actions configured in this way won't override any of the built-in shortcuts the associated widgets may have.

EDIT

Here's a simple demo. Note that, when the text-edit has the keyboard focus, 'Ctrl+P' will trigger the handler, but 'Ctrl+C won't, because it is a built-in shortcut. When the table has the keyboard focus, 'Ctrl+C' will copy the selected item as normal, but 'Ctrl+P' will do nothing.

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_())

Upvotes: 1

Related Questions