How to allow tab key pressing event in pyqt5

2019-07-18 13:04发布

问题:

Assuming that I have a QPushButton named button, I successfully do the following to allow click event:

class UI(object):
    def setupUi(self, Dialog):
        # ...
        self.button.clicked.connect(self.do_something)

    def do_something(self):
        # Something here

My question is: how can I call do_something() when the tab key is pressed? For instance, if I have a QlineEdit named tb_id, after entering a value and press tab key, do_something() method should be called in the same way as what clicked does above. How can I do that using pyqt5?

Thank you so much.

回答1:

To get what you want there are many methods but before pointing it by observing your code I see that you have generated it with Qt Designer so that code should not be modified but create another class that uses that code so I will place the base code:

from PyQt5 import QtCore, QtWidgets

class UI(object):
    def setupUi(self, Dialog):
        self.button = QtWidgets.QPushButton("Press Me")
        lay = QtWidgets.QVBoxLayout(Dialog)
        lay.addWidget(self.button)

class Dialog(QtWidgets.QDialog, UI):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        self.button.clicked.connect(self.do_something)

    @QtCore.pyqtSlot()
    def do_something(self):
        print("do_something")

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Dialog()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())

Also, I recommend you read the difference between event and signal in the world of Qt in What are the differences between event and signal in Qt since you speak of click event but in the world of Qt one must say clicked signal.

Now if going to the point there are the following options:

  • Using keyPressEvent:

class Dialog(QtWidgets.QDialog, UI):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        self.button.clicked.connect(self.do_something)

    @QtCore.pyqtSlot()
    def do_something(self):
        print("do_something")

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Tab:
            self.do_something()
  • Using an event filter:

class Dialog(QtWidgets.QDialog, UI):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        self.button.clicked.connect(self.do_something)

    @QtCore.pyqtSlot()
    def do_something(self):
        print("do_something")

    def eventFilter(self, obj, event):
        if obj is self and event.type() == QtCore.QEvent.KeyPress:
            if event.key() == QtCore.Qt.Key_Tab:
                self.do_something()
        return super(Dialog, self).eventFilter(obj, event)
  • Using activated signal of QShorcut:

class Dialog(QtWidgets.QDialog, UI):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.setupUi(self)
        self.button.clicked.connect(self.do_something)
        shortcut = QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Tab), self)
        shortcut.activated.connect(self.do_something)

    @QtCore.pyqtSlot()
    def do_something(self):
        print("do_something")

From the previous methods I prefer the latter because you do not need to overwrite anything and you can connect to several functions.

On the other hand, only events are detected when the focus is in the Qt window.



回答2:

I assume you put your widget in QDialog widget, so if you want to implement your own key press event, you should override the keyPressEvent of your Dialog widget, then it can behave as you like.

Here's an example,

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog

class UI(QDialog):

    def __init__(self):
        super(UI, self).__init__()
        # ...
        self.button.clicked.connect(self.do_something)

    def do_something(self):
        # Something here

    def keyPressEvent(self, event):
        # when press key is Tab call your function
        if event.key() == Qt.Key_Tab:
           self.do_something()