signal and slot in pyside


Signals and Slots in PySide

This page describes the use of signals and slots in PySide. The emphasis is on illustrating the use of so-called new-style signals and slots, although the traditional syntax is also given as a reference.

PyQt’s new-style signals and slots were introduced in PyQt v4.5. The main goal of this new-style is to provide a more Pythonic syntax to Python programmers. PySide uses PSEP 100 [pyside.org] as its implementation guideline.

QtGui.QPushButton("Call someFunc")

  • QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), someFunc)
  •  
  • ...
  •  

    QtGui.QPushButton("Call someFunc")

  • button.clicked.connect(someFunc)
  •  
  • ...
  •  

    QtCore, QtGui

  •  
  • # define a function that will be used as a slot
  • def sayHello():
  •     print 'Hello world!'
  •  
  • app = QtGui.QApplication(sys.argv)
  •  
  • button = QtGui.QPushButton('Say hello!')
  •  
  • # connect the clicked signal to the sayHello slot
  • button.clicked.connect(sayHello)
  • button.show()
  •  
  • sys.exit(app.exec_())
  •  

    • Next, some arguments are added. This is a modified Hello World version. Some arguments are added to the slot and a new signal is created.

     

    1. #!/usr/bin/env python
    2.  
    3. import sys
    4. from PySide import QtCore
    5.  
    6. # define a new slot that receives a string and has
    7. # 'saySomeWords' as its name
    8. @QtCore.Slot(str)
    9. def saySomeWords(words):
    10.     print words
    11.  
    12. class Communicate(QtCore.QObject):
    13.     # create a new signal on the fly and name it 'speak'
    14.     speak = QtCore.Signal(str)
    15.  
    16. someone = Communicate()
    17. # connect signal and slot
    18. someone.speak.connect(saySomeWords)
    19. # emit 'speak' signal
    20. someone.speak.emit("Hello everybody!")

     

    • Add some overloads. A small modification of the previous example, now with overloaded decorators.

     

    1. #!/usr/bin/env python
    2.  
    3. import sys
    4. from PySide import QtCore
    5.  
    6. # define a new slot that receives a C 'int' or a 'str'
    7. # and has 'saySomething' as its name
    8. @QtCore.Slot(int)
    9. @QtCore.Slot(str)
    10. def saySomething(stuff):
    11.     print stuff
    12.  
    13. class Communicate(QtCore.QObject):
    14.     # create two new signals on the fly: one will handle
    15.     # int type, the other will handle strings
    16.     speakNumber = QtCore.Signal(int)
    17.     speakWord = QtCore.Signal(str)
    18.  
    19. someone = Communicate()
    20. # connect signal and slot properly
    21. someone.speakNumber.connect(saySomething)
    22. someone.speakWord.connect(saySomething)
    23. # emit each 'speak' signal
    24. someone.speakNumber.emit(10)
    25. someone.speakWord.emit("Hello everybody!")

     

    • An example with slot overloads and more complicated signal connections and emissions:

     

    1. #!/usr/bin/env python
    2.  
    3. import sys
    4. from PySide import QtCore
    5.  
    6. # define a new slot that receives an C 'int' or a 'str'
    7. # and has 'saySomething' as its name
    8. @QtCore.Slot(int)
    9. @QtCore.Slot(str)
    10. def saySomething(stuff):
    11.     print stuff
    12.  
    13. class Communicate(QtCore.QObject):
    14.     # create two new signals on the fly: one will handle
    15.     # int type, the other will handle strings
    16.     speak = QtCore.Signal((int,), (str,))
    17.  
    18. someone = Communicate()
    19. # connect signal and slot. As 'int' is the default
    20. # we have to specify the str when connecting the
    21. # second signal
    22. someone.speak.connect(saySomething)
    23. someone.speak[str].connect(saySomething)
    24.  
    25. # emit 'speak' signal with different arguments.
    26. # we have to specify the str as int is the default
    27. someone.speak.emit(10)
    28. someone.speak[str].emit("Hello everybody!")

     

    • An example of an object method emitting a signal:

     

    1. #!/usr/bin/env python
    2.  
    3. import sys
    4. from PySide import QtCore
    5.  
    6. class Communicate(QtCore.QObject):    # !!! Must inherit QObject for signals
    7.    
    8.    speak = QtCore.Signal()
    9.  
    10.    def __init__(self):
    11.        # !!! Must init QObject else runtime error: PySide.QtCore.Signal object has no attribute ‘emit’
    12.        super(Communicate, self).__init__()
    13.  
    14.    def speakingMethod():
    15.        self.speak.emit()
    16.  
    17. someone = Communicate()
    18. someone.speakingMethod()

     

    • Signals are runtime objects owned by instances, they are not class attributes:

     

    1. Communicate.speak.connect(saySomething)   # Erroneous: refers to class Communicate, not an instance of the class
    2.  
    3. # raises exception: AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'

     

    QtCore import Signal as pyqtSignal

  • from PySide.QtCore import Slot as pyqtSlot
  •  

    or

     

    1. QtCore.pyqtSignal = QtCore.Signal
    2. QtCore.pyqtSlot = QtCore.Slot

     

    This way any call to pyqtSignal or pyqtSlot will be translated to a Signal or Slot call.

    Categories: