Connecting signals and slots
#!/usr/bin/env python
#
# [SNIPPET_NAME: Connecting signals and slots]
# [SNIPPET_CATEGORIES: PyQt4]
# [SNIPPET_DESCRIPTION: Different ways to connect signals and slots]
# [SNIPPET_AUTHOR: Darren Worrall <[email protected]>]
# [SNIPPET_LICENSE: GPL]
# [SNIPPET_DOCS: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#connecting-disconnecting-and-emitting-signals]
# example signalsandslots.py
# In this example we will simulate some things that are done automatically
# if you are building your ui's with Qt Designer and the pyuic4 tools
import sys
from PyQt4 import QtGui, QtCore
class SignalsAndSlots(QtGui.QWidget):
"""
A few signal and slot examples
"""
def __init__(self):
# create GUI
QtGui.QMainWindow.__init__(self)
self.setWindowTitle('Signals and Slots')
# Set the window dimensions
self.resize(450,400)
# vertical layout for widgets
self.vbox = QtGui.QVBoxLayout()
self.setLayout(self.vbox)
# Create a button which we will manually connect to a slot
self.man_btn = QtGui.QPushButton('Manually connected', self)
self.vbox.addWidget(self.man_btn)
# Manually connect the clicked signal to it's handler, as we have done
# in other examples
self.connect(self.man_btn, QtCore.SIGNAL('clicked()'), self.manual_slot)
# Create a button which we will automatially connect to a slot
self.brokenbtn = QtGui.QPushButton("'Broken' Auto Button", self)
# For autoconnection to work we have to call setobject name. When
# using the designer this is done automatially
self.brokenbtn.setObjectName('brokenbtn')
self.vbox.addWidget(self.brokenbtn)
# Create a button which we will automatially connect to a slot, only
# a bit more carefully :)
self.workingbtn = QtGui.QPushButton("'Working' Auto Button", self)
self.workingbtn.setObjectName('workingbtn')
self.vbox.addWidget(self.workingbtn)
# Finally a text edit area to show some results
self.log_window = QtGui.QTextEdit()
self.vbox.addWidget(self.log_window)
# read only, sorry folks ;)
self.log_window.setReadOnly(True)
# Automatcally connect signals to slots by their name. This is also
# done for you if you use the result of pyuic4, in the setupUi call
QtCore.QMetaObject.connectSlotsByName(self)
def manual_slot(self):
"""
This slot/handlier is manually connected in __init__
"""
# A manually connected slot, as pre previous examples. No drama :)
msg = 'This slot was manually connected, and is called once'
self.log_window.append(msg)
def on_brokenbtn_clicked(self):
"""
This slot is connected automatically in connectSlotsByName
"""
# connectSlotsByName found this handler - it starts with on_, followed
# by the object name, followed by the signal this should be connected
# to. However, as you will see, it is called twice...
msg = 'This slot was automatically connected, and is called twice'
self.log_window.append(msg)
@QtCore.pyqtSlot()
def on_workingbtn_clicked(self):
"""
This slot is connected automatically in connectSlotsByName
"""
# Using the same logic this slot is connected to the 'working' button
# and only called once. The reason for this is that a lot of Qt signals
# are overloaded, and if you dont specify which specific variant you
# are interested in, then _all_ of them will be connected. Once way to
# specify the specific signal is by use of the decorator above - in
# this case, we will be connected to the signal with no arguments
#
# It is better explained in the documentation:
# http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#connecting-slots-by-name
msg = 'This slot was automatically connected, and is called once'
self.log_window.append(msg)
# If the program is run directly or passed as an argument to the python
# interpreter then create a SignalsAndSlots instance and show it
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
gui = SignalsAndSlots()
gui.show()
app.exec_()