События и сигналы PyQt6

События и сигналы PyQt6

В этой части руководства мы исследуем события и сигналы в программах PyQt6.

События в PyQt6

Приложения с графическим интерфейсом управляются событиями. События в первую очередь инициируются пользователем приложения, но также могут генерироваться другими способами, такими как подключение к Интернету, оконные менеджеры или таймеры. Когда мы вызываем метод приложения exec(), приложение входит в основной цикл. Основной цикл получает события и отправляет их объектам.

В модели событий есть три элемента:

  • источник событий источник событий
  • объект события объект события
  • Цель события Цель события

Источник событий — это объект изменения состояния, генерирующий события. Объект события (событие) инкапсулирует изменение состояния источника события. Цель события — это объект, который необходимо уведомить. Объект источника события делегирует задачу обработки события цели события.

PyQt6 имеет уникальный механизм сигналов и слотов для обработки событий, используемый для связи между объектами и запускаемый при возникновении определенного события. Слот может представлять собой любой вызываемый скрипт Python. Когда сигнализируется о соединении, вызывается скрипт слота.

Аннотация: Это можно понимать как хуки или обратные вызовы.

Сигналы и слоты PyQt6

В следующем примере показаны сигналы и слоты PyQt6.

# file: signals_slots.py
#!/usr/bin/python

"""
ZetCode PyQt6 tutorial

本例中,把 QSlider 触发的事件和 QLCDNumber 插槽绑定起来

Author: Jan Bodnar
Website: zetcode.com
"""

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (QWidget, QLCDNumber, QSlider,
        QVBoxLayout, QApplication)


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        lcd = QLCDNumber(self)
        sld = QSlider(Qt.Orientation.Horizontal, self)

        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)
        sld.valueChanged.connect(lcd.display)

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('Signal and slot')
        self.show()


def main():
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

В этом примере QtGui.QLCDNumberи QtGui.QSlider. Мы можем изменить число на дисплее, перетаскивая ползунок.

sld.valueChanged.connect(lcd.display)

valueChangedПривяжите событие ползунка displayк слоту дисплея.

Отправитель — это объект, который запускает сигнал, получатель — это объект, который получает сигнал, а слот — это метод, который реагирует на сигнал.

PyQt6 переопределяет обработчики событий

В PyQt6 обработчики событий обычно переопределяются.

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

# file: reimplement_handler.py
#!/usr/bin/python

"""
ZetCode PyQt6 tutorial

本例中,我们重新实现了一个事件处理器。

Author: Jan Bodnar
Website: zetcode.com
"""

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QWidget, QApplication


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.setGeometry(300, 300, 350, 250)
        self.setWindowTitle('Event handler')
        self.show()


    def keyPressEvent(self, e):
        
        if e.key() == Qt.Key.Key_Escape.value:
            self.close()


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

В этом примере мы переопределяем keyPressEventобработчик событий для

def keyPressEvent(self, e):
    
    if e.key() == Qt.Key.Key_Escape.value:
        self.close()

Нажмите кнопку Escape, и приложение закроется.

Объект события PyQt6

Объект события — это объект Python, который содержит ряд атрибутов, описывающих событие, а конкретное содержимое зависит от инициированного события.

# file: event_object.py
#!/usr/bin/python

"""
ZetCode PyQt6 tutorial

本例中,在标签组件里,展示了鼠标的坐标。

Author: Jan Bodnar
Website: zetcode.com
"""

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QWidget, QApplication, QGridLayout, QLabel


class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        grid = QGridLayout()

        x = 0
        y = 0

        self.text = f'x: {
      
      x},  y: {
      
      y}'

        self.label = QLabel(self.text, self)
        grid.addWidget(self.label, 0, 0, Qt.AlignmentFlag.AlignTop)

        self.setMouseTracking(True)
        self.setLayout(grid)

        self.setGeometry(300, 300, 450, 300)
        self.setWindowTitle('Event object')
        self.show()


    def mouseMoveEvent(self, e):

        x = int(e.position().x())
        y = int(e.position().y())

        text = f'x: {
      
      x},  y: {
      
      y}'
        self.label.setText(text)


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

В этом примере координаты мыши отображаются в компоненте метки.

self.setMouseTracking(True)

По умолчанию отслеживание мыши отключено.При движении мыши компонент может получать события только при нажатии мыши. Включите отслеживание мыши, и вы сможете получать события, только перемещая мышь, не нажимая кнопку мыши.

def mouseMoveEvent(self, e):

    x = int(e.position().x())
    y = int(e.position().y())
    ...

eОбъект события, содержащий данные при срабатывании события. С помощью методов position().x()и e.position().y()можно получить координаты мыши.

self.text = f'x: {
      
      x},  y: {
      
      y}'
self.label = QLabel(self.text, self)

Значения координат x и y отображаются в QLabelкомпоненте.

Триггер событий PyQt6

Иногда вам нужно знать, кто является триггером события, и в PyQt6 есть метод, позволяющий получить триггер события.

event_sender.py
#!/usr/bin/python

"""
ZetCode PyQt6 tutorial

In this example, we determine the event sender
object.

Author: Jan Bodnar
Website: zetcode.com
"""

import sys
from PyQt6.QtWidgets import QMainWindow, QPushButton, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        btn1 = QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QPushButton("Button 2", self)
        btn2.move(150, 50)

        btn1.clicked.connect(self.buttonClicked)
        btn2.clicked.connect(self.buttonClicked)

        self.statusBar()

        self.setGeometry(300, 300, 450, 350)
        self.setWindowTitle('Event sender')
        self.show()


    def buttonClicked(self):

        sender = self.sender()

        msg = f'{
      
      sender.text()} was pressed'
        self.statusBar().showMessage(msg)


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

В этом примере есть две кнопки. buttonClickedВызов метода триггера определяет, какая кнопка вызвала событие.

btn1.clicked.connect(self.buttonClicked)
btn2.clicked.connect(self.buttonClicked)

Обе кнопки привязаны к одному слоту.

def buttonClicked(self):

    sender = self.sender()

    msg = f'{
      
      sender.text()} was pressed'
    self.statusBar().showMessage(msg)

В строке состояния приложения показано, какая кнопка была нажата.

Графика: триггер события

Триггерный сигнал PyQt6

QObjectСигналы могут запускаться активно. В примере ниже показано, как вызвать пользовательский сигнал.

# file: custom_signal.py
#!/usr/bin/python

"""
ZetCode PyQt6 tutorial

In this example, we show how to
emit a custom signal.

Author: Jan Bodnar
Website: zetcode.com
"""

import sys
from PyQt6.QtCore import pyqtSignal, QObject
from PyQt6.QtWidgets import QMainWindow, QApplication


class Communicate(QObject):

    closeApp = pyqtSignal()


class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.c = Communicate()
        self.c.closeApp.connect(self.close)

        self.setGeometry(300, 300, 450, 350)
        self.setWindowTitle('Emit signal')
        self.show()


    def mousePressEvent(self, e):

        self.c.closeApp.emit()


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

Создан closeAppсигнал, который срабатывает при нажатии мыши и QMainWindowпривязан к закрытому слоту.

class Communicate(QObject):

    closeApp = pyqtSignal()

Свойства внешнего класса Communicate pyqtSignalСоздает сигнал.

self.c = Communicate()
self.c.closeApp.connect(self.close)

Пользовательский сигнал closeAppпривязан QMainWindowк слоту выключения файла .

def mousePressEvent(self, event):

    self.c.closeApp.emit()

При нажатии кнопки мыши в окне closeAppсрабатывает сигнал и программа завершает работу.

В этой главе руководства мы рассмотрели сигналы и слоты.

Supongo que te gusta

Origin blog.csdn.net/zy_dreamer/article/details/132701104
Recomendado
Clasificación