SoFunction
Updated on 2024-11-13

PyQt5 Everyday Must Learn Events and Signals

In this section we will explore how PyQt5's events and signals are implemented in the application.

Events

All GUI applications are event-driven. Application events are generated primarily by the user, but they can also be generated by other methods, such as an Internet connection, a window manager, or a timer. When we call the exec_() method of the application, the application enters the main loop. The main loop detects various events and sends them to the event object.

In the event model, there are three participants:

  • event source
  • event object
  • event target

An event source is an object whose state changes and generates an event. The event object (event) is the object encapsulated in the event source whose state changes. Event targets are objects that wish to be notified. The event source object represents the task of processing an event to the event target.

PyQt5 uses a unique signal and slot mechanism to handle events. Signals and slots are used for communication between objects, and are emitted when a particular event occurs. Slots can be arbitrary Python calls. Signals are emitted when connected to slots are called.

Signals & slots

This is a simple example demonstrating PyQt5 signals and slots.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 Tutorial

In this example, we connect the QSlider's slide signal to a QLCDNumber.

Author: my world you have been here before
Blog: /weiaitaowang
Last Edit: August 1, 2016
"""

import sys
from  import (QApplication, QWidget, QSlider, 
QLCDNumber, QVBoxLayout)
from  import Qt

class Example(QWidget):

 def __init__(self):
 super().__init__()

 ()

 def initUI(self):

 lcd = QLCDNumber(self)
 sld = QSlider(, self)

 vbox = QVBoxLayout()
 (lcd)
 (sld)

 (vbox)
 ()

 (300, 300, 250, 150)
 ('Signal/slot') 
 ()

if __name__ == '__main__':

 app = QApplication()
 ex = Example()
 (app.exec_())

In our example, and will be used. We change the LCD numbers by dragging the slider.

()

Here, the valueChanged signal of the slider is connected to the display slot of the lcd.

The transmitter is the object sending the signal. Receiver is the object receiving the signal. The slot is the method that feeds back to the signal.

post-program execution

Override system event handlers

Events are often handled in PyQt5 by rewriting the event to handle the program.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 Tutorial

In this example, we execute the event handler.

Author: My World You've Been Here Before
Blog: /weiaitaowang
Last Edit: August 1, 2016
"""

import sys
from  import QApplication, QWidget
from  import Qt

class Example(QWidget):

 def __init__(self):
 super().__init__()

 ()

 def initUI(self):

 (300, 300, 250, 150)
 ('Event Handling') 
 ()

 def keyPressEvent(self, e):
 if () == Qt.Key_Escape:
  ()

if __name__ == '__main__':

 app = QApplication()
 ex = Example()
 (app.exec_())

In our example, we reimplement the keyPressEvent() event handler.

def keyPressEvent(self, e):
 if () == Qt.Key_Escape:
 ()

If we press Esc on the keyboard, the application terminates.

Event sender

To easily distinguish between multiple event sources connected to the same event target, the sender() method can be used in PyQt5.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 Tutorial

In this example, we determine the event sender object.

Author: My World You've Been Here Before
Blog: /weiaitaowang
Last Edit: August 1, 2016
"""

import sys
from  import QApplication, QMainWindow, QPushButton

class Example(QMainWindow):

 def __init__(self):
 super().__init__()

 ()

 def initUI(self):

 btn1 = QPushButton('Button One', self)
 (30, 50)

 btn2 = QPushButton('Button Two', self)
 (150, 50)

 ()
 ()

 ()

 (300, 300, 300, 150)
 ('Event Send') 
 ()

 def buttonClicked(self):

 sender = ()
 ().showMessage(() + ' pressed ')

if __name__ == '__main__':

 app = QApplication()
 ex = Example()
 (app.exec_())

There are two buttons in our example. Both buttons are connected to the buttonClicked() method, and we respond to the clicked button by calling the sender() method.

()
()

Both buttons are connected to the same slot.

def buttonClicked(self):

 sender = ()
 ().showMessage(() + ' pressed ')

We determine the source of the signal by calling the sender() method. In the status bar of the application, the label of the pressed button is displayed.

post-program execution

Customized transmitter signals

Objects created from a QObject can emit signals. In the following example, we will see how we can customize the emitting signal.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 Tutorial

In this example, we show how to emit a signal as.

Author: My World You Were Here
Blog: /weiaitaowang
Last Edit: August 1, 2016
"""

import sys
from  import QApplication, QMainWindow
from  import pyqtSignal, QObject

class Communicate(QObject):
 closeApp = pyqtSignal()

class Example(QMainWindow):

 def __init__(self):
 super().__init__()

 ()

 def initUI(self):

  = Communicate()
 ()

 (300, 300, 300, 150)
 ('Transmitting signals') 
 ()

 def mousePressEvent(self, event):

 ()

if __name__ == '__main__':

 app = QApplication()
 ex = Example()
 (app.exec_())

We create a new signal called closeApp. This signal is firing the mouse press event. This signal is attached to the close() slot in the QMainWindow.

class Communicate(QObject):
 closeApp = pyqtSignal()

Creates the Communicate class that inherits from QObject and has a property of the pyqtSignal() class.

 = Communicate()
()

Connect our customized closeApp signal to the close() slot in QMainWindow.

def mousePressEvent(self, event):
 ()

The closeApp signal is fired (emit) when a click action occurs with our mouse in the program window. The application program terminates.

This is the whole content of this article.