Связь сигналов и слотов PyQt в Python

Обычно скрипт Python выполняется сверху вниз следующим образом:

  • Получить исходные данные.
  • Обрабатывать входные данные для получения выходных данных.
  • Вывести результаты на экран или в файл.

Это называется процедурным программированием.

Когда вы создаете программу GUI, вы используете вместо этого событийно-управляемое программирование. В парадигме событийно-управляемого программирования программа имеет следующий поток:

  • Создавайте виджеты, такие как метки, строки редактирования и кнопки.
  • Запустите цикл событий, ожидающий событий.
  • Реагируйте на события по мере их возникновения, выполняя вызываемые функции.

Обратите внимание, что вызываемый объект — это функция, метод или объект, реализующий метод __call__().

Содержание

Что такое сигналы и слоты 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().
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *