50

I've seen some example code for PySide slots that uses the @QtCore.Slot decorator, and some that does not. Testing it myself, it doesn't seem to make a difference. Is there a reason I should or should not use it? For example, in the following code:

import sys
from PySide import QtCore

# the next line seems to make no difference
@QtCore.Slot()
def a_slot(s):
    print s

class SomeClass(QtCore.QObject):
    happened = QtCore.Signal(str)
    def __init__(self):
        QtCore.QObject.__init__(self)
    def do_signal(self):
        self.happened.emit("Hi.")

sc = SomeClass()
sc.happened.connect(a_slot)
sc.do_signal()

the @QtCore.Slot decorator makes no difference; I can omit it, call @QtCore.Slot(str), or even @QtCore.Slot(int), and it still nicely says, "Hi."

The same seems to be true for PyQt's pyqtSlot.

JasonFruit
  • 7,764
  • 5
  • 46
  • 61

3 Answers3

72

This link explains the following about the pyqtSlot decorator:

Although PyQt4 allows any Python callable to be used as a slot when connecting signals, it is sometimes necessary to explicitly mark a Python method as being a Qt slot and to provide a C++ signature for it. PyQt4 provides the pyqtSlot() function decorator to do this.

and

Connecting a signal to a decorated Python method also has the advantage of reducing the amount of memory used and is slightly faster.

Since the pyqtSlot decorator can take additional argument such as name, it allows different Python methods to handle the different signatures of a signal.

If you don't use the slot decorator, the signal connection mechanism has to manually work out all the type conversions to map from the underlying C++ function signatures to the Python functions. When the slot decorators are used, the type mapping can be explicit.

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
Austin Phillips
  • 15,228
  • 2
  • 51
  • 50
  • 3
    Thank you for that concise and complete answer. I've been relying mostly on the PySide documents, since that's the library I'm using, but I see the advantage of sorting through the PyQt ones. – JasonFruit Jan 21 '13 at 02:40
  • 4
    I don't entirely understand this answer -- if I'm defining my own slot (or overriding a built-in one for that matter), why would I need a C++ function signature (there's no C++ function...)? – simon May 11 '14 at 02:19
  • 4
    @simon Qt is implemented in C++ along with the signals/slots mechanism so at some point, even if you define your own signals/slots they will traverse the underlying C++ implementation. – Austin Phillips May 13 '14 at 01:39
  • @AustinPhillips what differentiates a Qt slot from a non-Qt slot in Pyside? I am never sure what that means. Also, do we really provide C++ signatures in PySide when using the new-style signals and slots (as Jason does in his example above)? Also I have a slot that uses 'sender' and when I try to put `@QtCore.Slot()` before the definition, the slot doesn't work. So it doesn't seem universally true that adding the decorator is a Good Thing. – eric Jul 28 '14 at 14:04
  • 1
    Just found this thread: http://stackoverflow.com/questions/18015684/pyside-qtcore-slot-decorator-does-not-work-with-self-sender-inside-a-method – eric Jul 28 '14 at 16:15
  • 2
    * it is sometimes necessary to explicitly mark a Python method as being a Qt slot*. I wonder what those *sometimes* are, it seems the document writer did not know. For example if I use QThread is it mandatory? if not then when. – dashesy Sep 04 '15 at 20:09
  • @dashesy It's necessary when you want to have different Python methods handle different signatures of the signal, per the accepted answer above. – Simon Hibbs Apr 05 '17 at 11:43
12

Austin has a good answer, and the answer I'm about to write is a bit outside the scope of your question, but it's something that has been confusing me and I imagine others will end up on this page wondering the same thing.

If you want to expose Python methods to JavaScript (using QTWebKit), then the @pyqtSlot decorator is mandatory. Undecorated methods are not exposed to JavaScript.

Mark E. Haase
  • 25,965
  • 11
  • 66
  • 72
9

In a multithreaded environment, it may be mandatory not to use the pyside Slot decorator, because it can cause signals to go to the wrong thread. See

Derived classes receiving signals in wrong thread in PySide (Qt/PyQt)

https://bugreports.qt.io/browse/PYSIDE-249

Community
  • 1
  • 1
Rudolf Cardinal
  • 738
  • 8
  • 11