На этом шаге мы рассмотрим понятие слота.
Классы PyQt5 поддерживают ряд методов, специально предназначенных для использования в качестве обработчиков сигналов. Такие методы называются слотами. Например, класс QApplication поддерживает слот quit(), завершающий текущее приложение. В примере ниже показан код, использующий этот слот.
# -*- coding: utf-8 -*- from PyQt5 import QtWidgets import sys app = QtWidgets.QApplication(sys.argv) button = QtWidgets.QPushButton("Завершить работу") button.clicked.connect(app.quit) button.show() sys.exit(app.exec_())
Любой пользовательский метод можно сделать слотом, для чего необходимо перед его реализацией вставить декоратор @pyqtSlot(). Формат декоратора:
@QtCore.pyqtSlot(*<Типы данных>, name=None, result=None)
В параметре <Типы данных> через запятую перечисляются типы данных параметров, принимаемых слотом, - например: bool или int. При задании типа данных C++ его название необходимо указать в виде строки. Если метод не принимает параметров, параметр <Типы данных> не указывается. В именованном параметре name можно передать название слота в виде строки - это название станет использоваться вместо названия метода, а если параметр name не задан, название слота будет совпадать с названием метода. Именованный параметр result предназначен для указания типа данных, возвращаемых методом, - если параметр не задан, то метод ничего не возвращает. Чтобы создать перегруженную версию слота, декоратор указывается последовательно несколько раз с разными типами данных. Пример использования декоратора @pyqtSlot() приведен ниже.
# -*- coding: utf-8 -*- from PyQt5 import QtCore, QtWidgets import sys class MyClass(QtCore.QObject): def __init__(self): QtCore.QObject.__init__ (self) @QtCore.pyqtSlot() def on_clicked(self): print("Кнопка нажата. Слот on_clicked()") @QtCore.pyqtSlot(bool, name="myslot") def on_clicked2(self, status): print("Кнопка нажата. Слот myslot(bool)", status) obj = MyClass() app = QtWidgets.QApplication(sys.argv) button = QtWidgets.QPushButton("Нажми меня") button.clicked.connect(obj.on_clicked) button.clicked.connect(obj.myslot) button.show() sys.exit(app.exec_())
Результат работы приложения изображен на рисунке 1.
Рис.1. Результат работы приложения
PyQt не требует обязательного превращения в слот метода, который будет использоваться как обработчик сигнала. Однако это рекомендуется сделать, так как вызов слота в этом случае выполняется быстрее, чем вызов обычного метода.
Необязательный параметр <Тип соединения> метода connect() определяет тип соединения между сигналом и обработчиком. На этот параметр следует обратить особое внимание при использовании в приложении нескольких потоков, т. к. изменять GUI-поток из другого потока нельзя. В параметре можно указать один из следующих атрибутов класса Qtcore.Qt:
# Эти два обработчика будут успешно назначены и выполнены button.clicked.connect(on_clicked) button.clicked.connect(on_clicked) # А эти два обработчика назначены не будут button.clicked.connect(on_clicked, Qt.Core.Qt.Autoconnection | QtCore.Qt.UniqueConnection) button.clicked.connect(on_clicked, Qt.Core.Qt.Autoconnection | QtCore.Qt.UniqueConnection) # Тем не менее, эти два обработчика будут назначены, поскольку они разные button.clicked.connect(on_clicked, Qt.Core.Qt.Autoconnection | QtCore.Qt.UniqueConnection) button.clicked.connect(obj.on_clicked, Qt.Core.Qt.Autoconnection | QtCore.Qt.UniqueConnection)
На следующем шаге мы рассмотрим блокировку и удаление обработчика.