События и сигналы в PyQt5
События
Все GUI приложения основаны на обработке событий. В основном события создаются пользователем приложения. Но могут создаваться и другими источниками: например интернет соединением, управлением окон или таймером. Когда мы вызываем метод приложенияexec_(),
приложение запускает основную цикл.
Основной цикл загружает события и
посылает их к объектам.
В модели событий существует три участника:
-
событие источник
-
событие объект
-
событие цель
У PyQt5 уникальный механизм работы с событиями — это сигналы (signal) и слоты (slot). Сигналы и слоты используются для связи между объектами. Сигнал выпускается когда конкретное событие возникает. Слотом может быть все, что можно вызвать на языке Python. Слот вызывается когда связанный с ним сигнал появляется.
Сигналы и слоты
Это простой пример демонстрирующий сигналы и слоты в PyQt5.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
В этом примере мы связываем сигнал от QSlider к слоту в QLCDNumber.
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
import sys
from PyQt5.QtCore import Qt
from PyQt5.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.Horizontal, self)
vbox = QVBoxLayout()
vbox.addWidget(lcd)
vbox.addWidget(sld)
self.setLayout(vbox)
sld.valueChanged.connect(lcd.display)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Signal & slot')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
В примере мы выводим на экран
QtGui.QLCDNumber и QtGui.QSlider.
Мы изменяем число lcd
перетаскивая мышкой кнопку ползунка.
sld.valueChanged.connect(lcd.display)Здесь мы соединяем сигнал
valueChanged
ползунка со слотом ИЗОБРАЖЕНИЯ числа
lcd.
Тот кто посылает это объект, посылающий сигнал. Получатель, это объект получающий сигнал. Слот это метод, который реагирует на сигнал.
Переписывание обработчика событий
События в PyQt5 часто обрабатывают переделывая обработку событий.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
В этом примере мы переделываем обработку событий.
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Event handler')
self.show()
def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape:
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
В нашем примере мы переписываем обработчик
нажатия клавиш keyPressEvent().
def keyPressEvent(self, e):
if e.key() == Qt.Key_Escape:
self.close()
Посылающий событие
Иногда очень удобно знать какое виджет послал сигнал. Для этого, PyQt5 имеет методsender().
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
В этом примере мы определяем объект посылающий событие.
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
import sys
from PyQt5.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, 290, 150)
self.setWindowTitle('Event sender')
self.show()
def buttonClicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + ' was pressed')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Мы имеем две кнопки. В методе buttonClicked()
мы определяем какая кнопка была нажата
при помощи метода sender().
btn1.clicked.connect(self.buttonClicked) btn2.clicked.connect(self.buttonClicked)Обе кнопки присоединены к одному и тому же слоту.
def buttonClicked(self):
sender = self.sender()
self.statusBar().showMessage(sender.text() + ' was pressed')
Мы определили источник сигнала вызывая
метод sender(). В строке
состояния мы показали наименование
нажатой кнопки.
Создание сигналов
Объекты, порожденные отQObject
могут порождать сигналы. В следующем
примере мы увидим как мы можем создать
пользовательский сигнал.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
В этом примере мы покажем как создать сигнал.
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.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, 290, 150)
self.setWindowTitle('Emit signal')
self.show()
def mousePressEvent(self, event):
self.c.closeApp.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Мы создали новый сигнал с именем closeApp.
Этот сигнал инициируется во время
события нажатия мыши. Этот сигнал
связывается со слотом close()
объекта QMainWindow.
class Communicate(QObject):
closeApp = pyqtSignal()
Сигнал создается методом pyqtSignal()
как атрибут расширения класса Communicate.
Этот метод принадлежит классу Qobject.self.c = Communicate() self.c.closeApp.connect(self.close)Пользовательский сигнал
closeApp
подключается к слоту close()
сласса QMainWindow.
def mousePressEvent(self, event):
self.c.closeApp.emit()
Когда мы нажимаем на окне мышкой,
создается сигнал closeApp.
Приложение заканчивается.
Комментариев нет:
Отправить комментарий