7 августа 2008 в 13:16

PyQt4 — Сигналы и события перевод

События
События это важная часть 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().
Перевод: ZetCode
Andrey M. @Amka
карма
15,7
рейтинг 0,0
Пользователь
Похожие публикации
Самое читаемое Разработка

Комментарии (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):

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