PySide插槽装饰器是否必要?

时间:2013-01-20 05:15:49

标签: python pyqt pyside signals-slots

我见过一些使用@ QtCore.Slot装饰器的PySide插槽的示例代码,有些则没有。自己测试一下,它似乎没有什么区别。有没有理由我应该或不应该使用它?例如,在以下代码中:

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()

@ QtCore.Slot装饰器没有区别;我可以省略它,调用@ QtCore.Slot(str),甚至@ QtCore.Slot(int),它仍然很好地说,“嗨。”

PyQt的pyqtSlot似乎也是如此。

3 个答案:

答案 0 :(得分:44)

This链接解释了有关pyqtSlot装饰器的以下内容:

  

虽然PyQt4允许任何Python可调用时用作插槽   连接信号时,有时需要明确标记a   Python方法作为Qt槽并为其提供C ++签名   它。 PyQt4提供pyqtSlot()函数装饰器来执行此操作。

  

将信号连接到装饰的Python方法也有   减少使用的内存量的优点是略有的   更快。

由于pyqtSlot装饰器可以采用其他参数,例如name,因此它允许不同的Python方法处理信号的不同签名。

如果不使用插槽装饰器,则信号连接机制必须手动计算所有类型转换,以便从底层C ++函数签名映射到Python函数。使用槽装饰器时,类型映射可以是显式的。

答案 1 :(得分:6)

奥斯汀有一个很好的答案,而我即将写的答案有点超出了你的问题的范围,但它让我感到困惑,我想其他人最终会这个页面想知道同样的事情。

如果要将Python方法公开给JavaScript(使用QTWebKit),那么@pyqtSlot装饰器是必需的。未修饰的方法不会暴露给JavaScript。

答案 2 :(得分:5)

在多线程环境中,可能必须不使用pyside Slot装饰器,因为它可能导致信号进入错误的线程。参见

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

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