pythonpyqt5event-handlingkeyeventqlineedit

How to call function when space key is pressed inside the lineEdit


I want to call a function that checks words count in a lineEdit whenever I press space key inside the lineEdit. But how can I do that. After executing the python file press 'Start Game' to go to the lineEdit. Thanks!
Here's my code:

from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel, QLineEdit, QPushButton, QTextBrowser, QStackedWidget, QWidget, QLCDNumber, QComboBox
from PyQt5 import uic
import sys
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtCore import QThread, pyqtSignal, Qt
import random

class UI(QMainWindow):
    def __init__(self):
        super(UI, self).__init__()

        # Load the ui file
        uic.loadUi("Typing_test_UI.ui", self)

        # Define our widgets
        self.textBrowser = self.findChild(QTextBrowser, "textBrowser")
        self.lineEdit = self.findChild(QLineEdit, "lineEdit")
        self.counter = self.findChild(QLCDNumber, "counter")
        self.startBtn = self.findChild(QPushButton, "startBtn")
        self.timeCombo = self.findChild(QComboBox, "timeCombo")
        self.difficultyCombo = self.findChild(QComboBox, "difficultyCombo")
        self.stackedWidget = self.findChild(QStackedWidget, "stackedWidget")
        self.startPage = self.findChild(QWidget, "startPage")
        self.gamePage = self.findChild(QWidget, "gamePage")
        self.scorePage = self.findChild(QWidget, "scorePage")
        self.highScoreLabel = self.findChild(QLabel, "highScoreLabel")
        self.scoreLabel = self.findChild(QLabel, "scoreLabel")
        self.retryBtn = self.findChild(QPushButton, "retryBtn")
        

        self.space_count = 0


        self.startBtn.clicked.connect(self.start_game)
        self.retryBtn.clicked.connect(self.goto_home_page)

        
        # Show the app
        self.show()

    def start_game(self):
        self.stackedWidget.setCurrentWidget(self.gamePage)

        self.textBrowser.clear()

        with open("Typing_sentences.txt", "r") as f:
            all_texts = f.readlines()

        lines_of_text = len(all_texts)

        self.textBrowser.append(all_texts[random.randint(0, lines_of_text-1)])

    def goto_home_page(self):
        self.stackedWidget.setCurrentWidget(self.startPage)



app = QApplication(sys.argv)
UIWindow = UI()
app.exec_()

The sentences for a function in my code:
He found himself sitting at his computer, typing whatever came to mind. He was on a website entitled 10 fast fingers. This site tested how fast you were at typing. So he typed. He was currently typing about himself typing, which is odd in a way. He was now describing about how he was typing about himself typing.
The Internet is the global system of interconnected computer networks that uses the Internet protocol suite to communicate between networks and devices. It is a network of networks that consists of private, public, academic, business, and government networks of local to global scope, linked by a broad array of electronic, wireless, and optical networking technologies. The Internet carries a vast range of information resources and services, such as the inter-linked hypertext documents and applications of the World Wide Web (WWW), electronic mail, telephony, and file sharing.

The ui file:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>801</width>
    <height>443</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>801</width>
    <height>443</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>801</width>
    <height>443</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <property name="sizePolicy">
    <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QStackedWidget" name="stackedWidget">
      <property name="currentIndex">
       <number>2</number>
      </property>
      <widget class="QWidget" name="startPage">
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
         <widget class="QWidget" name="widget_3" native="true">
          <widget class="QComboBox" name="timeCombo">
           <property name="geometry">
            <rect>
             <x>280</x>
             <y>60</y>
             <width>201</width>
             <height>41</height>
            </rect>
           </property>
           <property name="font">
            <font>
             <pointsize>11</pointsize>
            </font>
           </property>
           <item>
            <property name="text">
             <string>1 Minute</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>2 Minutes</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>5 Minutes</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>10 Minutes</string>
            </property>
           </item>
          </widget>
          <widget class="QComboBox" name="difficultyCombo">
           <property name="geometry">
            <rect>
             <x>280</x>
             <y>130</y>
             <width>201</width>
             <height>41</height>
            </rect>
           </property>
           <property name="font">
            <font>
             <pointsize>12</pointsize>
            </font>
           </property>
           <item>
            <property name="text">
             <string>Easy</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>Medium</string>
            </property>
           </item>
           <item>
            <property name="text">
             <string>Hard</string>
            </property>
           </item>
          </widget>
          <widget class="QPushButton" name="startBtn">
           <property name="geometry">
            <rect>
             <x>230</x>
             <y>230</y>
             <width>301</width>
             <height>61</height>
            </rect>
           </property>
           <property name="font">
            <font>
             <pointsize>16</pointsize>
            </font>
           </property>
           <property name="text">
            <string>Start Game</string>
           </property>
          </widget>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="gamePage">
       <layout class="QGridLayout" name="gridLayout_2">
        <item row="0" column="0" alignment="Qt::AlignRight|Qt::AlignTop">
         <widget class="QWidget" name="widget_2" native="true">
          <property name="layoutDirection">
           <enum>Qt::LeftToRight</enum>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout">
           <item alignment="Qt::AlignRight">
            <widget class="QLCDNumber" name="counter">
             <property name="minimumSize">
              <size>
               <width>150</width>
               <height>30</height>
              </size>
             </property>
             <property name="maximumSize">
              <size>
               <width>150</width>
               <height>16777215</height>
              </size>
             </property>
             <property name="layoutDirection">
              <enum>Qt::RightToLeft</enum>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QWidget" name="widget" native="true">
          <layout class="QGridLayout" name="gridLayout">
           <item row="0" column="0" colspan="2">
            <widget class="QTextBrowser" name="textBrowser"/>
           </item>
           <item row="1" column="0" colspan="2">
            <widget class="QLineEdit" name="lineEdit">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="minimumSize">
              <size>
               <width>0</width>
               <height>45</height>
              </size>
             </property>
             <property name="maximumSize">
              <size>
               <width>16777215</width>
               <height>45</height>
              </size>
             </property>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="scorePage">
       <widget class="QLabel" name="scoreLabel">
        <property name="geometry">
         <rect>
          <x>240</x>
          <y>90</y>
          <width>300</width>
          <height>71</height>
         </rect>
        </property>
        <property name="minimumSize">
         <size>
          <width>300</width>
          <height>0</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>16777215</width>
          <height>100</height>
         </size>
        </property>
        <property name="font">
         <font>
          <pointsize>20</pointsize>
         </font>
        </property>
        <property name="text">
         <string>Score: 0</string>
        </property>
       </widget>
       <widget class="QPushButton" name="retryBtn">
        <property name="geometry">
         <rect>
          <x>652</x>
          <y>320</y>
          <width>121</width>
          <height>64</height>
         </rect>
        </property>
        <property name="minimumSize">
         <size>
          <width>64</width>
          <height>64</height>
         </size>
        </property>
        <property name="text">
         <string>Retry</string>
        </property>
        <property name="iconSize">
         <size>
          <width>64</width>
          <height>64</height>
         </size>
        </property>
       </widget>
       <widget class="QLabel" name="highScoreLabel">
        <property name="geometry">
         <rect>
          <x>291</x>
          <y>185</y>
          <width>200</width>
          <height>18</height>
         </rect>
        </property>
        <property name="minimumSize">
         <size>
          <width>200</width>
          <height>0</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>16777215</width>
          <height>50</height>
         </size>
        </property>
        <property name="font">
         <font>
          <pointsize>9</pointsize>
         </font>
        </property>
        <property name="text">
         <string>High Score: 0</string>
        </property>
       </widget>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>801</width>
     <height>26</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuPapers">
    <property name="title">
     <string>Options</string>
    </property>
    <widget class="QMenu" name="menuTest_papers">
     <property name="title">
      <string>Test papers</string>
     </property>
     <addaction name="actionRandom"/>
     <addaction name="actionChoose"/>
    </widget>
    <addaction name="menuTest_papers"/>
    <addaction name="actionReset"/>
   </widget>
   <addaction name="menuPapers"/>
  </widget>
  <action name="actionRandom">
   <property name="text">
    <string>Random</string>
   </property>
  </action>
  <action name="actionChoose">
   <property name="text">
    <string>Choose</string>
   </property>
  </action>
  <action name="actionReset">
   <property name="text">
    <string>Reset High Score</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

Solution

  • Here is an example of installing an Event Filter on the QLineEdit as suggested. See the inline comments for details and explanation.

    ...
    
    class UI(QMainWindow):
        def __init__(self):
            super(UI, self).__init__()
            # Load the ui file
            uic.loadUi("Typing_test_UI.ui", self)
            # Define our widgets
            ...
            ...
            self.spaceFilter = SpaceFilter(parent=self)  # init filter
            self.spaceFilter.spacePressed.connect(self.my_function)  # connect to the signal
            self.lineEdit.installEventFilter(self.spaceFilter)  # install on lineedit
            self.space_count = 0
            self.startBtn.clicked.connect(self.start_game)
            self.retryBtn.clicked.connect(self.goto_home_page)
            # Show the app
            self.show()
    
    
        def my_function(self):   # custom function that runs when space bar is
            for i in range(5):   # pressed while typing in the line edit
                for i in range(1000):
                    print(str(i), end="\r")
    
        def start_game(self):
            self.stackedWidget.setCurrentWidget(self.gamePage)
            self.textBrowser.clear()
            with open("list1.txt", "r") as f:
                all_texts = f.readlines()
            lines_of_text = len(all_texts)
            self.textBrowser.append(all_texts[random.randint(0, lines_of_text-1)])
    
        def goto_home_page(self):
            self.stackedWidget.setCurrentWidget(self.startPage)
    
    class SpaceFilter(QObject):  # the event filter object
    
        spacePressed = pyqtSignal()   # the signal emited when space bar detected
    
        def eventFilter(self, widget, event):
            if event.type() == QEvent.KeyPress:  # listen for key press events
                if event.key() == Qt.Key.Key_Space:  # if the key is the space bar
                    self.spacePressed.emit()         # emit the signal
            return False