Связь сигналов и слотов PyQt в Python
Обычно скрипт Python выполняется сверху вниз следующим образом:
- Получить исходные данные.
- Обрабатывать входные данные для получения выходных данных.
- Вывести результаты на экран или в файл.
Это называется процедурным программированием.
Когда вы создаете программу GUI, вы используете вместо этого событийно-управляемое программирование. В парадигме событийно-управляемого программирования программа имеет следующий поток:
- Создавайте виджеты, такие как метки, строки редактирования и кнопки.
- Запустите цикл событий, ожидающий событий.
- Реагируйте на события по мере их возникновения, выполняя вызываемые функции.
Обратите внимание, что вызываемый объект — это функция, метод или объект, реализующий метод __call__().
- Что такое сигналы и слоты PyQT?
- Сигналы
- Слоты
- Пример сигналов и слотов PyQt
- Использование сигналов, отправляющих данные
Что такое сигналы и слоты PyQT?
Для связи событий с вызываемыми объектами программы PyQt использует механизм сигналов и слотов в Python.
Сигналы
Сигнал — это особое свойство объекта, которое выдается при возникновении события. Событием может быть действие пользователя, тайм-аут или завершение асинхронной операции.
Слоты
Слот — это вызываемый объект, который может принимать сигнал и реагировать на него. Чтобы реагировать на события, вы подключаете сигналы к слотам. Когда вы подключаете сигнал к слоту, слот будет выполняться при испускании сигнала.
В PyQt все подклассы класса QObject могут отправлять и получать сигналы. Почти все классы в PyQt являются подклассами класса QObject.
Давайте рассмотрим пример, чтобы понять, как работает механизм сигналов и слотов PyQt.
Пример сигналов и слотов PyQt
Следующая программа отображает окно с кнопкой. Когда вы нажимаете кнопку, программа показывает сообщение о нажатии в консоли:
import sys from PyQt6.QtWidgets import( QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout ) class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # set the window title self.setWindowTitle('Qt Signals & Slots') # create a button widget and connect its clicked signal # to a method button = QPushButton('Click me') button.clicked.connect(self.button_clicked) # place the buton on window using a vertical box layout layout = QVBoxLayout() self.setLayout(layout) layout.addWidget(button) # show the window self.show() def button_clicked(self): print('clicked') if __name__ == '__main__': app = QApplication(sys.argv) # create the main window and display it window = MainWindow() # start the event loop sys.exit(app.exec())
Как это работает (мы сосредоточимся только на сигналах и слотах).
- Сначала создайте кнопку с помощью виджета QPushButton:
button = QPushButton('Click me')
- Во-вторых, подключите сигнал clicked к методу on_clicked(слоту):
button.clicked.connect(self.button_clicked)
В общем случае синтаксис подключения сигнала к слоту выглядит следующим образом:
sender_object.signal_name.connect(receiver_object.slot_name)
Также вы можете подключить сигнал к слоту, передавая слот сигналу в качестве ключевого аргумента. Например:
button = QPushButton('Click me', clicked=self.button_clicked)
В-третьих, определите метод on_clicked, который выводит сообщение о щелчке на терминал:
def on_clicked(self): print('clicked')
При нажатии кнопки QPushButton излучает сигнал clicked, который запускает подключенный слот on_clicked.
Обратите внимание, что следующий код размещает кнопку в окне, используя вертикальную компоновку.
layout = QVBoxLayout() self.setLayout(layout) layout.addWidget(button)
Использование сигналов, отправляющих данные
Сигнал может переносить данные, которые предоставляют состояние объекта при возникновении события. Например, сигнал textChanged QLineEdit содержит текст, введенный в виджет.
Если сигнал несет данные, подключенный слот может их принять.
Следующая программа показывает виджеты QLineEdit и QLabel. Когда вы печатаете что-то в QLineEdit, QLabel отобразит это соответствующим образом:
import sys from PyQt6.QtWidgets import( QApplication, QWidget, QLabel, QLineEdit, QVBoxLayout ) class MainWindow(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('Qt Signals & Slots') # create widgets label = QLabel() line_edit = QLineEdit() line_edit.textChanged.connect(label.setText) # place the widgets layout = QVBoxLayout() layout.addWidget(label) layout.addWidget(line_edit) self.setLayout(layout) # show the window self.show() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec())
Как это работает.
- Сначала создайте виджет QLabel. Виджет QLabel имеет метод setText(), который устанавливает его содержимое.
label = QLabel()
- Во-вторых, создайте новый виджет QLineEdit:
line_edit = QLineEdit()
- В-третьих, подключите сигнал textChanged к методу setText объекта QLabel:
line_edit.textChanged.connect(label.setText)
Когда вы печатаете что-либо в QLineEdit:
- Сигнал textChanged отправляет текст.
- QLabel получает текст и передает его методу setText().