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

http://zetcode.com/tutorials/pyqt4/eventsandsignals/
  • Перевод
События
События это важная часть GUI программирования. События генерируются пользователями или же системой. Когда мы вызываем метод exec() приложение запускает основной цикл. Он получаем события и отправляет их объектам. Trolltech представляет уникальный механизм сигналов и слотов.

Сигналы и слоты
Сигналы генерируются когда пользователь щелкает по кнопке, отмечает чекбокс и др. Сигналы также могут быть оправлены и окружением. Например, когда срабатывает таймер. Слот — это метод, который реагирует на сигнал.
#!/usr/bin/python

import sys
from PyQt4 import QtGui, QtCore

class SigSlot(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowTitle('signal & slot')

        lcd = QtGui.QLCDNumber(self)
        slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)

        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(slider)

        self.setLayout(vbox)
        self.connect(slider, QtCore.SIGNAL('valueChanged(int)'),
            lcd, QtCore.SLOT('display(int)') )

        self.resize(250, 150)

app = QtGui.QApplication(sys.argv)
qb = SigSlot()
qb.show()
sys.exit(app.exec_())

В данном случае мы отображаем бегунок и LCD циферблат. Номер на циферблате изменяется перетаскиванием бегунка.
self.connect(slider, QtCore.SIGNAL('valueChanged(int)'),
    lcd, QtCore.SLOT('display(int)'))

Здесь мы соединяем сигнал бегунка valueChanged() со слотом display() циферблата.
Метод connect() имеет четыре параметра. Sender(отправитель) — объект который отправляет сигнал. Signal (сигнал) — генерируемый сигнал. Receiver(получатель) — объект, который получает сигнал. Slot (слот) — метод, который реагирует на сигнал.
Сигналы и слоты

Изменение обработчика события
События в PyQt4 обрабатываются в зачастую с помощью изменения обработчиков событий.
#!/usr/bin/python

import sys
from PyQt4 import QtGui, QtCore

class Escape(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowTitle('escape')
        self.resize(250, 150)
        self.connect(self, QtCore.SIGNAL('closeEmitApp()'), QtCore.SLOT('close()') )

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.close()

app = QtGui.QApplication(sys.argv)
qb = Escape()
qb.show()
sys.exit(app.exec_())

В нашем примере мы реинициализируем обработчик события keyPressEvent().
def keyPressEvent(self, event):
    if event.key() == QtCore.Qt.Key_Escape:
        self.close()

Если мы щёлкнем по кнопке Escape, то закроем приложение.

Генерирование сигналов
Объекты создаваемые из QtCore.QObject могут генерировать сигналы. Если мы щелкаем по кнопке, гененрируется сигнал clicked(). В следующем примере мы покажем как это сделать.
#!/usr/bin/python

import sys
from PyQt4 import QtGui, QtCore

class Emit(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowTitle('emit')
        self.resize(250, 150)
        self.connect(self, QtCore.SIGNAL('closeEmitApp()'), QtCore.SLOT('close()') )

def mousePressEvent(self, event):
self.emit(QtCore.SIGNAL('closeEmitApp()'))

app = QtGui.QApplication(sys.argv)
qb = Emit()
qb.show()
sys.exit(app.exec_())

Мы создаём новый сигнал closeEmitApp(). Этот сигнал генерируется когда происходит нажатие кнопки мышки.
def mousePressEvent(self, event):
    self.emit(QtCore.SIGNAL('closeEmitApp()'))

Сигнал создаётся с помощью метода emit().
self.connect(self, QtCore.SIGNAL('closeEmitApp()'), QtCore.SLOT('close()'))

Здесь мы соединяет созданный нами сигнал closeEmitApp() со слотом close().
Метки:
  • +1
  • 20,4k
  • 8
Поделиться публикацией
Похожие публикации
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 8
  • 0
    Не написано как средствами PyQt4 можно свои сигналы/слоты создавать, без этого многое теряется.
    • 0
      Угу, вот как раз над этим и думаю сейчас.
      • 0
        Любая функция класса наследника от QObject может быть слотом, былбы сигнал подходящий.
        Сгенерировать сигнал можно например так:
        self.emit(QtCore.SIGNAL("addingItem(QTreeWidgetItem*)"),item)
        А с помощью декораторов можно еще уменьшить объем кода (избавиться от некоторых connect-ов)
      • 0
        любой метод может быть слотом, а сигналы создаются автоматически. Т.е. не нужно писать signals: или public slots: как в C++ версии.

        http://www.diotavelli.net/PyQtWiki/Threading,_Signals_and_Slots
        http://zetcode.com/tutorials/pyqt4/eventsandsignals/
        http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots
      • 0
        Удобно еще вместо слота в connect использовать lambda функции в случаях когда удобно использовать lambda функции :) т.е. когда и слота нет подходящего, и используется в одном месте, и кода совсем мало.
        • 0
          > Если мы щелкаем по кнопке Escape, то мы закроем приложение.
          Как-то странно звучит.. Может нажимаем на кнопку Escape?
          • 0
            Спасибо, исправил.
          • 0
            Вызов слота обработчика сигнала от QAction без использования connect:
            @QtCore.pyqtSignature("")
            def on_actionExit_triggered(self):

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