WutsSoftware
WutsSoftware

Reputation: 53

Have enter behave as key_down in QAbstractTableModel tableView

I'm using a QAbstractTableModel in PyQt5 and Qt Designer to create a data table. I need a little help to find a simple way to make the "Enter" keyPressEvent to move down the table as if the Key_Down button was pressed. The following code captures the Enter key press event. How do I make it move the cursor?

I have searched the forums and googled this problem, but I haven't been able to find a solution yet. I have tried creating a custom event to pass that along in place of 'ev', but that didn't work.

def keyPressEvent(self, ev):        
    if ev.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
        print("Enter key pressed")

Upvotes: 1

Views: 475

Answers (1)

eyllanesc
eyllanesc

Reputation: 243973

You have to have the new QModelIndex using the moveCursor() method, and set the new selection using the setCurrentIndex() method of the selectionModel().

from PyQt5 import QtCore, QtGui, QtWidgets


class TableView(QtWidgets.QTableView):
    def keyPressEvent(self, event):
        if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
            index = self.moveCursor(
                QtWidgets.QAbstractItemView.MoveDown, QtCore.Qt.NoModifier
            )
            command = self.selectionCommand(index, event)
            self.selectionModel().setCurrentIndex(index, command)
        else:
            super(TableView, self).keyPressEvent(event)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    model = QtGui.QStandardItemModel(10, 4)
    w = TableView()
    w.setModel(model)
    w.show()

    sys.exit(app.exec_())

If you are using Qt Designer there are 2 possible implementations:

  1. Promote the QTableView for use in Qt Designer.

  2. Implement the logic using an eventFilter.

In this case I will show how to implement the second method:

class EventFilter(QtCore.QObject):
    def __init__(self, view):
        super(EventFilter, self).__init__(view)
        if not isinstance(view, QtWidgets.QAbstractItemView):
            raise TypeError("{} must be a QAbstractItemView".format(view))
        self._view = view
        self._view.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self._view and event.type() == QtCore.QEvent.KeyPress:
            if event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
                index = self._view.moveCursor(
                    QtWidgets.QAbstractItemView.MoveDown, QtCore.Qt.NoModifier
                )
                command = self._view.selectionCommand(index, event)
                self._view.selectionModel().setCurrentIndex(index, command)
        return super(EventFilter, self).eventFilter(obj, event)

And then you set it in your QTableView:

event_filter = EventFilter(self.tableView)

Upvotes: 1

Related Questions