In diesem Abschnitt des PyQt4-Programmier-Tutorials untersuchen wir die in Anwendungen auftretenden Ereignisse und Signale.
Ereignisse sind ein wichtiger Teil der Programmierung von Benutzeroberflächen. Ereignisse werden von Nutzern oder dem System erzeugt. Wenn wir die exec_()-Methode einer Anwendung aufrufen, tritt sie in die Hauptschleife. Die Hauptschleife empfängt Ereignisse und sendet sie an die Objekte weiter. Trolltech hat ein einzigartiges Signal-Slot-System eingeführt.
Signale werden geworfen, wenn Nutzer einen Knopf drücken, einen Regler ziehen etc. Signale können außerdem durch die Umgebung ausgelöst werden, z.B. wenn eine Uhr tickt. Ein Slot ist eine Methode, die auf ein Signal reagiert. In Python kann alles aufrufbare ein Slot sein.
#!/usr/bin/python
# sigslot.py
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_())
In unserem Beispiel zeigen wir eine LCD-Ziffer und einen Regler an. Über das Ziehen des Reglers ändern wir die LCD-Ziffer.
self.connect(slider, QtCore.SIGNAL('valueChanged(int)'), lcd, QtCore.SLOT('display(int)') )
Wir verbinden ein valueChanged()-Signal des Schiebereglers mit dem display()-Slot der LCD-Ziffer.
Die connect()-Methode hat vier Parameter. Der Sender ist ein Objekt, das ein Signal sendet. Das Signal ist ein Signal, das geworfen wird. Der Empfänger ist ein Objekt, das ein Signal empfängt. Schließlich ist der Slot die Methode, die auf das Signal reagiert.
Abbildung: Signale & Slots
Ereignisse in PyQt werden vorwiegend durch die Neuimplementierung eines Ereignis-Handlers hergestellt.
#!/usr/bin/python
# escape.py
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_())
Im Beispiel reimplementieren wir den keyPressEvent()-Ereignis-Handler.
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
self.close()
Wenn wir die Escape-Taste drücken, schließen wir damit die Anwendung.
Objekte, die mittels des QtCore.QObject erzeugt wurden, können Signale werfen. Wenn wir auf einen Knopf drücken, wird ein clicked()-Signal erzeugt. Im folgenden Beispiel werden wir sehen, wie wir ein Signal werfen können.
#!/usr/bin/python
# emit.py
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_())
Wir erzeugen hier ein neues Signal namens closeEmitApp(). Dieses Signal wird während eines Mausklick-Ereignisses geworfen.
def mousePressEvent(self, event):
self.emit(QtCore.SIGNAL('closeEmitApp()'))
Werfen eines Signals mit der emit()-Methode.
self.connect(self, QtCore.SIGNAL('closeEmitApp()'), QtCore.SLOT('close()') )
Hier verbinden wir das von Hand erzeugte closeEmitApp()-Signal mit dem close()-Slot.