Events and Signals in PyQt4
In this part of the PyQt4 programming tutorial, we will explore events and singnals occuring in applications.Events
Events are an important part in any GUI program. Events are generated by users or by the system. When we call the application'sexec_()
method, the application enters the main loop. The main loop fetches events and sends them to the objects. Trolltech has introduced a unique signal and slot mechanism. Events are an important part in any GUI program. All GUI applications are event-driven. An application reacts to different event types which are generated during its life. Events are generated mainly by the user of an application. But they can be generated by other means as well. e.g. internet connection, window manager, timer. In the event model, there are three participants:
- event source
- event object
- event target
When we call the application's
exec_()
method, the application enters the main loop. The main loop fetches events and sends them to the objects. Signals and slots are used for communication between objects. A signal is emitted when a particular event occurs. A slot can be any Python callable. A slot is called when a signal connected to it is emitted. New API
PyQt4.5 introduced a new style API for working with signals and slots.QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), self.onClicked)This is the old style API.
button.clicked.connect(self.onClicked)The new style adheres more to the Python standards.
Signals & Slots
This is a simple example, demonstrating signals and slots in PyQt4.#!/usr/bin/pythonIn our example, we display a
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we connect a signal
of a QtGui.QSlider to a slot
of a QtGui.QLCDNumber.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
lcd = QtGui.QLCDNumber(self)
sld = QtGui.QSlider(QtCore.Qt.Horizontal, self)
vbox = QtGui.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()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
QtGui.QLCDNumber
and a QtGui.QSlider
. We change the lcd number by dragging the slider knob. sld.valueChanged.connect(lcd.display)Here we connect a
valueChanged
signal of the slider to the display
slot of the lcd number. The sender is an object that sends a signal. The receiver is the object, that receives the signal. The slot is the method, that reacts to the signal.
Figure: Signal & slot
Reimplementing event handler
Events in PyQt4 are processed often by reimplementing event handlers.#!/usr/bin/pythonIn our example, we reimplement the
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we reimplement an
event handler.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__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() == QtCore.Qt.Key_Escape:
self.close()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
keyPressEvent()
event handler. def keyPressEvent(self, e):If we click the escape button, the application terminates.
if e.key() == QtCore.Qt.Key_Escape:
self.close()
Event sender
Sometimes it is convenient to know, which widget is the sender of a signal. For this, PyQt4 has asender()
method. #!/usr/bin/pythonWe have two buttons in our example. In the buttonClicked() method we determine, which button we have clicked by calling the
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we determine the event sender
object.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
btn1 = QtGui.QPushButton("Button 1", self)
btn1.move(30, 50)
btn2 = QtGui.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')
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
sender()
method. btn1.clicked.connect(self.buttonClicked)Both buttons are connected to the same slot.
btn2.clicked.connect(self.buttonClicked)
def buttonClicked(self):We detemine the signal source by calling the
sender = self.sender()
self.statusBar().showMessage(sender.text() + ' was pressed')
sender()
method. In the statusbar of the application, we show the label of the button being pressed. Figure: Event sender
Emitting signals
Objects created fromQtCore.QObject
can emit signals. If we click on the button, a clicked()
signal is generated. In the following example we will see, how we can emit signals. #!/usr/bin/pythonWe create a new signal called
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we show how to emit a
custom signal.
author: Jan Bodnar
website: zetcode.com
last edited: October 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Communicate(QtCore.QObject):
closeApp = QtCore.pyqtSignal()
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__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()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
closeApp
. This signal is emitted, during a mouse press event. The signal is connected to the close()
slot of the QtGui.QMainWindow
. class Communicate(QtCore.QObject):We create a class based on a
closeApp = QtCore.pyqtSignal()
QtCore.QObject
. It creates a closeApp signal when instantiated. self.c = Communicate()An instance of the Communicate class is created. We connect a
self.c.closeApp.connect(self.close)
close()
slot of the QtGui.QMainWindow
to the closeApp signal. def mousePressEvent(self, event):When we click on the window with a mouse pointer, the
self.c.closeApp.emit()
closeApp
signal is emitted. In this part of the PyQt4 tutorial, we have covered signals and slots.
No comments:
Post a Comment