Шаг 47.
Библиотека PyQt5.
Обработка сигналов и событий. Назначение обработчиков сигналов

    На этом шаге мы рассмотрим различные способы назначения обработчиков сигналов.

    Чтобы обработать какой-либо сигнал, необходимо сопоставить ему функцию или метод класса, который будет вызван при наступлении события и станет его обработчиком.

    Каждый сигнал, поддерживаемый классом, соответствует одноименному атрибуту этого класса (отметим, что это именно атрибуты класса, а не атрибуты экземпляра). Так, сигнал clicked, генерируемый при щелчке мышью, соответствует свойству clicked. Каждый такой атрибут хранит экземпляр особого объекта, представляющего соответствующий сигнал.

    Чтобы назначить сигналу обработчик, следует использовать метод connect(), унаследованный от класса QObject. Форматы вызова этого метода таковы:

  <Компонент>.<Сигнал>.connect (<Обработчик>[, <Тип соединения>]) 
  <Компонент>.<Сигнал>.[<Тип>].connect (<Обработчик> [, <Тип соединения>])

    Здесь мы назначаем <Обработчик> для параметра <Сигнал>, генерируемого параметром <Компонент>. В качестве обработчика можно указать:

    Пример назначения функции on_clicked_button() в качестве обработчика сигнала clicked кнопки button:

  button.clicked.connect(on_clicked_button)

    Сигналы могут принимать произвольное число параметров, каждый из которых может относиться к любому типу данных. При этом бывает и так, что в классе существуют два сигнала с одинаковыми наименованиями, но разными наборами параметров. Тогда следует дополнительно в квадратных скобках указать <Тип> данных, принимаемых сигналом, - либо просто написав его наименование, либо задав его в виде строки. Например, оба следующих выражения назначают обработчик сигнала, принимающего один параметр логического типа:

  button.clicked[bool].connect(on_clicked_button) 
  button.clicked["bool"].connect(on_clicked_button)

    Одному и тому же сигналу можно назначить произвольное количество обработчиков. Это иллюстрирует код из приведенного ниже примера, где сигналу clicked кнопки назначены сразу четыре обработчика.

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets
import sys
def on_clicked():
    print("Кнопка нажата. Функция on_clicked()")
class MyClass():
    def __init__(self, x=0):
        self.x = x
    def __call__(self):
        print("Кнопка нажата. Метод MyClass.__call__()")
        print("x =", self.x)
    def on_clicked(self):
        print("Кнопка нажата. Метод MyClass.on_clicked()")

obj = MyClass()
app = QtWidgets.QApplication(sys.argv)
button = QtWidgets.QPushButton("Нажми меня")
# Назначаем обработчиком функцию
button.clicked.connect(on_clicked)
# Назначаем обработчиком метод класса
button.clicked.connect(obj.on_clicked)
# Назначаем обработчиком ссылку на экземпляр класса
button.clicked.connect(MyClass(10))
# Назначаем обработчиком анонимную функцию
button.clicked.connect(lambda: MyClass(5)())
button.show()
sys.exit(app.exec_())
Архив с файлом можно взять здесь.

    В четвертом обработчике мы использовали анонимную функцию. В ней мы сначала создаем объект класса MyClass, передав ему в качестве параметра число 5, после чего сразу же вызываем его как функцию, указав после конструктора пустые скобки:

  button.clicked.connect(lambda: MyClass(5)())

    Результат выполнения в окне консоли при щелчке на кнопке:


Рис.1. Результат работы приложения

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг