Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to call keyPressEvent in PyQt5 by returnPressed?

How to call keyPressEvent in PyQt5 by returnPressed?

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 2 Posters 21.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    KCocco
    wrote on 6 Jun 2019, 12:13 last edited by
    #1

    Hi,
    I'm currently using PyQt5, and I need to detect when return is pressed inside it.
    I currently have this code:

    self.intextbox.returnPressed.connect(self.keyPressEvent)
    

    and my event function:

        def keyPressEvent(self, e):
            if e.key() == 16777220: #16777220 seems to be enter
                self.appendtotextbox()
    

    however it throws the exception:
    <class 'TypeError'> keyPressEvent() missing 1 required positional argument: 'e' None TypeError: keyPressEvent() missing 1 required positional argument: 'e'

    How would I be able to achieve it? (intextbox is a QLineEdit)

    1 Reply Last reply
    0
    • D Offline
      D Offline
      Denni
      wrote on 6 Jun 2019, 15:37 last edited by Denni 6 Jun 2019, 15:44
      #2

      Resolving the problem:

      First I am going to do more than just answer this question I am going to try and also explain how one goes about perhaps solving this issue by oneself -- self sufficiency is a very important element for any programmer and should always be your first line of action

      So first I did a Google search on "pyqt5 keyPressEvent" I found numerous examples on how this is done.

      This particular example which was actually PyQt4 ( http://python.6.x6.nabble.com/Keypressevent-td1792690.html ) does cover the basic elements and has a semi-working program to help one understand the keypress-event (granted it has to be tweaked to be made pyqt5 python 3.7 compliant -- fix the print( ) function calls, remove in-code references to QtCore and QtGui as well as add a reference to QtWidgets). So here is a pyqt5 working version of that example:

      import sys
      
      from PyQt5.QtCore import *
      from PyQt5.QtGui  import *
      from PyQt5.QtWidgets import *
       
      class MainGui(object):
          def setupUi(self, MainWindow):
              MainWindow.resize(218, 379)
              self.centralwidget = QWidget(MainWindow)
              self.layout = QVBoxLayout(self.centralwidget)
              self.p_text = QPlainTextEdit(self.centralwidget)
              self.layout.addWidget(self.p_text)
              MainWindow.setCentralWidget(self.centralwidget)
      
              self.p_text.keyPressEvent = self.keyPressEvent
      
          def keyPressEvent(self, e):
              print("event", e)
              if e.key()  == Qt.Key_Return :
                  print(' return')
              elif e.key() == Qt.Key_Enter :   
                  print(' enter')
      
      if __name__ == "__main__":
          app = QApplication(sys.argv)
          MainWindow = QMainWindow()
          ui = MainGui()
          ui.setupUi(MainWindow)
          MainWindow.show()
          sys.exit(app.exec_())
      

      So as you can see to grab the KeyPress Event we have to have a handle to the object (self.p_text) and we have to set that objects keyPressEvent to your local function (self.p_text.keyPressEvent = self.keyPressEvent) with (self.keyPressEvent) being our local function. Now while this works its not very pretty code-wise nor very simple and my motto is always K.I.S.S. (Keep It Simple but Smart) and I stress the Simple part because making it unnecessarily more complex, while it might need more intelligence to do, is technically not all that Smart since it is not easily understood a few months down the road even by the original coder.

      Also keep in mind that this intercepts the normal keypress event (aka it overrides the function) and as such destroys the normal functionality of that event handler which would mean we would then need to also recode all of its functionality. So to fix this I did a quick Google search of "pyqt5 keyPressEvent pass through" and found this: ( https://stackoverflow.com/questions/27475940/pyqt-connect-to-keypressevent ) and this explains how to catch the event and then pass it on so that it is handled properly. So with that determined let us take the above code and make it a bit more pythonic and not destroy the basic functionality.

      # Try not to include more than what you actually need
      from sys import exit as sysExit
      
      from PyQt5.QtCore    import Qt
      #from PyQt5.QtGui     import
      from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
      from PyQt5.QtWidgets import QPlainTextEdit, QHBoxLayout
      
      class CenterObject(QPlainTextEdit):
          # This of course handles our core object from which we want  
          # to capture the keypress event and thus gives that handle 
          # that we need in a much cleaner manner
          def __init__(self):
              QPlainTextEdit.__init__(self)
              
          # since this Class is our handle we can simply override
          # its keyPressEvent directly
          def keyPressEvent(self, keyEvent):
              # This passes the Event along its merry way to be handled as it normally would be
              # Note this could be done first or last or in the middle just as long as its done
              # The where it is handled part is greatly dependent upon what you are planning to 
              # do. Still it is an event so the sooner the better -- also you can change what is 
              # being passed on as well and if so this would naturally come after you have made 
              # whatever changes you want to make -- you could (conditionally) block this event 
              # from completing by simply not passing it on
              super(CenterObject, self).keyPressEvent(keyEvent)
      
              print("Event :", keyEvent)
              if keyEvent.key()  == Qt.Key_Return :
                  print('*** Return pressed')
              elif keyEvent.key() == Qt.Key_Enter :   
                  print('*** Enter pressed')
      
      class CenterPane(QWidget):
          # While this class does not currently contain much what it does 
          # contain is essential and it allows for expansion later on --
          # for example what if instead of a single textbox one wants a
          # tree and a list view that would be handled here
          def __init__(self):
              QWidget.__init__(self)
      
              objCntrPane = CenterObject()
              hbox = QHBoxLayout(self)
              hbox.addWidget(objCntrPane)
       
      class MainWindow(QMainWindow):
          def __init__(self, parent=None):
              super(MainWindow, self).__init__(parent)
              winLeft = 100
              winTop = 100
              winWidth = 400
              winHeight = 300
      
              self.setWindowTitle('Main Window')
              self.setGeometry(winLeft, winTop, winWidth, winHeight)
              self.setCentralWidget(CenterPane())
      
      # This routine needs to be made as simple as possible
      if __name__ == "__main__":
          # Note: Do not use "sys.argv" unless you actually plan to handle command
          # line directives as it is more secure as well as much simpler
          app = QApplication([])  
      
          GUI = MainWindow()
          GUI.show()
      
          sysExit(app.exec_())
      

      So there you have it -- not only how to properly handle the keyPressEvent but also the how to find an answer on your own. Oh by the way thank you for this question as I had not actually known how to do this myself until I looked into answering this question but it is something I was going to need to know myself.

      madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

      1 Reply Last reply
      3
      • K Offline
        K Offline
        KCocco
        wrote on 6 Jun 2019, 15:57 last edited by KCocco 6 Jun 2019, 15:57
        #3

        Thanks. I did do a Google search but many of the answers didn't seem to be working for me and the other websites looked awful so I didn't even bother trying.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          Denni
          wrote on 6 Jun 2019, 16:21 last edited by
          #4

          Your welcome -- and I understand I think my 2 searches required me to look at a few websites before finding something useful -- so all I can say is never get discouraged, never give up -- basically I can often find something faster than I can get a response to a posted question so I always do that first -- and frankly sometimes its the search criterion one uses that helps find that needle in the mountain of hay that is the internet which is why I posted what I searched for -- the Truth is out there :) you just got to find the correct light switch in order to see it

          madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

          1 Reply Last reply
          1

          4/4

          6 Jun 2019, 16:21

          • Login

          • Login or register to search.
          4 out of 4
          • First post
            4/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved