PyQt - Unbound and Bound Signals



In PyQt,unbound signals are class-level attributes that define the signals' properties, while bound signals are associated with specific instances and can be connected to slots and emitted to trigger actions within the GUI. In this chapter we will understand the concept of Unbound and bound signal in PyQt.

Unbound Signal

In PyQt, unbound signal are basically a class attribute.When we define a signal within a class, it is initially unbound. This means that the signal is not associated with any specific instance of the class. It serves as a blueprint for creating bound signals later on.

Example: Unbound signal

In this example, my_signal is an unbound signal initially as it is a class attribute initially until a class object is created. We then create an instance of MyObject and connect a lambda function to the signal. When the signal is emitted with the value 42, the connected lambda function is executed, printing "Received value: 42" to the console.

from PyQt5.QtCore import QObject, pyqtSignal

class MyObject(QObject):
   # Define an unbound signal
   my_signal = pyqtSignal(int)

obj = MyObject()  # Create an instance of MyObject
obj.my_signal.connect(lambda value: print(f"Received value: {value}"))

# Emit the signal
obj.my_signal.emit(42)

Output

Received value: 42

Bound Signal

In PyQt, bound signal is associated with a specific instance of a class. When we reference an unbound signal as an attribute of an instance, PyQt automatically binds the instance to the signal. This binding process is similar to how Python creates bound methods from class functions.

Methods in Bound signal

Bound signal uses some functions to fascilitate its usage −

  • connect() − This method is used to connect a slot to the signal. Slots are functions or methods that are called in response to a signal being emitted.
  • disconnect() − This function is used to disconnects a previously connected slot from the signal.
  • emit() − This method emits the signal, triggering any connected slots to execute.

A bound signal has a signal attribute, which represents the signature of the signal.

Example: Disconnecting Slots

In this example, we first connect a slot to the signal, emit the signal, and then disconnect the slot. When the signal is emitted again, the previously connected slot is no longer called.

class MyObject(QObject):
   # Define a signal
   my_signal = pyqtSignal(int)

obj = MyObject()  # Create an instance of MyObject
slot = lambda value: print(f"Received value: {value}")
obj.my_signal.connect(slot)

# Emit the signal
obj.my_signal.emit(42)

# Disconnect the slot
obj.my_signal.disconnect(slot)

# Emit the signal again
obj.my_signal.emit(100)

Output

Received value: 42

Overloaded Signal

In PyQt, a signal is said to be overloaded when it supports mutliple signature. Each signature corresponds to a specific set of argument types. To select a particular signature of an overloaded signal, we can index the signal with the desired signature.

A signature is a sequence of types, where each type can be a Python type object or a string representing a C++ type. PyQt automatically normalizes C++ type names for consistency and ease of use.

Example: Overloaded signal

In this example, my_signal is overloaded to support both integer and string arguments. We connect different slots to handle each type of argument and emit the signal with corresponding values.

class MyObject(QObject):
   # Define an overloaded signal
   my_signal = pyqtSignal([int], [str])

obj = MyObject()  # Create an instance of MyObject
obj.my_signal[int].connect(lambda value: print(f"Received integer value: {value}"))
obj.my_signal[str].connect(lambda value: print(f"Received string value: {value}"))

# Emit the signal with different types of arguments
obj.my_signal[int].emit(42)
obj.my_signal[str].emit("Hello PyQt")

Output

Received integer value: 42
Received string value: Hello PyQt
Advertisements