
- PyQt - Home
- PyQt - Introduction
- PyQt - Environment
- PyQt - Hello World
- PyQt - Major Classes
- PyQt - Using Qt Designer
- PyQt - Meta Objects
- PyQt Signals & Slots
- PyQt - Signals and Slots
- PyQt - Support and Signals
- PyQt - Unbound and Bound Signals
- PyQt - New Signals with PyQtSignal
- PyQt - Connecting, Disconnecting, & Emitting Signals
- PyQt - Slot decorator
- PyQt - Slot Connection
- PyQt Layouts
- PyQt - Layout Management
- PyQt - QBoxLayout
- PyQt - QGridLayout
- PyQt - QFormLayout
- PyQt - QHBoxLayout
- PyQt - QVBoxLayout
- PyQt - QStackedLayout
- PyQt - QGraphicsGridLayout
- PyQt - QGraphicsAnchorLayout
- PyQt - QGraphicsLayout
- PyQt - QGraphicsLinearLayout
- PyQt Basic Widgets
- PyQt - Basic Widgets
- PyQt - Qlabel Widget
- PyQt - QLineEdit Widget
- PyQt - QPushButton Widget
- PyQt - QRadioButton Widget
- PyQt - QCheckBox Widget
- PyQt - QComboBox Widget
- PyQt - QSpinBox Widget
- PyQt - QMessageBox
- PyQt - QDialogButtonBox Widget
- PyQt - QFontComboBox Widget
- PyQt - QDoubleSpinBox Widget
- PyQt - QToolBox Widget
- PyQt - QMenuBar, QMenu & Qaction Widgets
- PyQt - QToolTip
- PyQt - QInputDialog Widget
- PyQt - QFontDialog Widget
- PyQt - QDialog Widget
- PyQt - QFileDialog Widget
- PyQt - QTab Widget
- PyQt - QSplitter Widget
- PyQt - QDock Widget
- PyQt - QStatusBar Widget
- PyQt - QTabBar
- PyQt - QList Widget
- PyQt - QScrollBar Widget
- PyQt - QProgressBar
- PyQt - QCalendar Widget
- PyQt - QMessageBox Widget
- PyQt - QPlainTextEdit
- PyQt - QDateEdit
- PyQt - QDateTimeEdit
- PyQt - QTimeEdit
- PyQt - QTextEdit
- PyQt - QTextBrowser
- PyQt - QScrollArea
- PyQt - Drag and Drop
- PyQt - Multiple Document Interface
- PyQt - QDialog Class
- PyQt Views
- PyQt - QColumnView
- PyQt - QTableView
- PyQt Drawing API
- PyQt - Drawing API
- PyQt - Drawing a Line
- PyQt - Drawing a Rectangle
- PyQt - Drawing a Triangle
- PyQt - Drawing a Circle
- PyQt - Drawing a Ellipse
- PyQt - Drawing a Polygon
- PyQt - Geometric Transformation
- PyQt - Drawing Effect
- PyQt Groups
- PyQt - QButtonGroup
- PyQt - QGroupBox
- PyQt Effects
- PyQt - Effects
- PyQt - Opacity Effect
- PyQt - QGraphicsBlur Effect
- PyQt - QGraphicsColorize Effect
- PyQt - QGraphicsDropShadow Effect
- PyQt Events
- PyQt - Event Handling
- PyQt - Drag & Drop Events
- PyQt - File Open Event
- PyQt - Action Event
- PyQt - Hide Event
- PyQt - Resize Event
- PyQt Database
- PyQt - Database Handling
- PyQt Essentials
- PyQt - BrushStyle Constants
- PyQt - QClipboard
- PyQt - QPixmap Class
- PyQt Useful Resources
- PyQt - Quick Guide
- PyQt - Useful Resources
- PyQt - Discussion
PyQt - New Signals with PyQtSignal
PyQt automatically defines signals for all Qt's built-in signals, but sometimes custom signals are required to ease the communication between different parts of the application. This is where pyqtSignal helps the developers to define and create new custom signals as class attributes using PyQtSignal factory.
Syntax and Parameters of pyqtSignal
We can define a new signal using pyqtSignal as class attributes as follows −
PyQt6.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]])
In the above syntax the parameters passed to the pyqtSignals plays different role as follows −
- types − Defines the types that constitute the C++ signature of the signal. Each type can be a Python type object, a string representing a C++ type, or a sequence of type arguments defining multiple signal overloads.For example, int, float etc.
- name(optional) − It specifies the name of the signal. If omitted, the name of the class attribute is used.
- revision(optional) − It specifies the revision of the signal exported to QML. (Qt Modeling Language)
- arguments(optional) − It specifies the names of the signal's arguments exported to QML.
Defining New Signal
A new signal in PyQt specifies an event or condition that is emitted by an object when some specific action occurs or a certain state changes. When a new signal is emitted the objects whihc connected to these signals can execute code in response which enables effective communication and interaction between different parts of the application.
Example of Signal Definition
from PyQt6.QtCore import QObject, pyqtSignal class Foo(QObject): # Define a signal called 'closed' with no arguments. closed = pyqtSignal() # Define a signal called 'rangeChanged' with two integer arguments. range_changed = pyqtSignal(int, int, name='rangeChanged') # Define a signal called 'valueChanged' with two overloads: int and QString. valueChanged = pyqtSignal([int], ['QString'])
Guidelines for Defining New Signals
- New Signals should only be defined in sub-classes of QObject.
- New Signals must be part of the class definition and cannot be added dynamically after class definition.
- New Signals defined using pyqtSignal are automatically added to the class's QMetaObject, making them accessible in Qt Designer and through the QMetaObject API.
Caution with Overloaded Signal
When we define overloaded signals i.e the signal contains more then one signature type of the signal, we should take caution when dealing with Python types that does not have corresponding C++ types.It's possible to have overloaded signals with different Python signatures but identical C++ signatures, leading to unexpected behavior.
Example of overloaded signal with unexpected behaviour
class Foo(QObject): # This will cause problems because each has the same C++ signature. cautiousSignal = pyqtSignal([dict], [list])
PyQt will consider both [dict] and [list] of array type internally leading to unexpected behaviour of signal.
Example of New Simple Signal
In the below example we define a PyQt class Counter which is inherited from QObject. We define a custom new signal that emits an integer when invoked.The increment method increases the internal _value attribute by 1 and emits the valueChanged signal with the updated value. An instance of Counter is created, and a lambda function is connected to its valueChanged signal to print the current value when the increment method is called.
from PyQt6.QtCore import QObject, pyqtSignal class Counter(QObject): valueChanged = pyqtSignal(int) def __init__(self): super().__init__() self._value = 0 def increment(self): self._value += 1 self.valueChanged.emit(self._value) counter = Counter() counter.valueChanged.connect(lambda value: print(f"Counter value: {value}")) counter.increment()
Output
Counter value: 1
Example of Custom new Signal with Arguments
In this example we defined a Worker class that is inherited from QObject. A new custom signal job_done is defined using pyqtSignal that emits a string.
The do_work method simulates work and emits the job_done signal with a message. An instance of Worker is created, and a lambda function is connected to its job_done signal, printing the worker's status when the task is completed.
from PyQt6.QtCore import QObject, pyqtSignal class Worker(QObject): job_done = pyqtSignal(str) def do_work(self): # Simulating some work result = "Task completed successfully" self.job_done.emit(result) worker = Worker() worker.job_done.connect(lambda message: print(f"Worker status: {message}")) worker.do_work()
Output
Worker status: Task completed successfully
Example of Overloaded new Signal
In this example, we're using QVariant as the type argument for the signal, and specifying the argument name as 'data'. When emitting the signal, we pass the dictionary as the argument.
Using QVariant allows us to pass complex data types like dictionaries between PyQt objects via signals.
from PyQt6.QtCore import QObject, pyqtSignal, QVariant class Loader(QObject): data_loaded = pyqtSignal(QVariant, arguments=['data']) def load_data(self): # Simulating data loading data_dict = {"key1": "value1", "key2": "value2"} self.data_loaded.emit(data_dict) loader = Loader() loader.data_loaded.connect(lambda data: print(f"Data loaded: {data}")) loader.load_data()
Output
Data loaded: {'key1': 'value1', 'key2': 'value2'}