PySide插槽装饰器是否必要?

Jas*_*uit 35 python pyqt signals-slots pyside

我已经看到了一些使用@ 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()
Run Code Online (Sandbox Code Playgroud)

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

PyQt的pyqtSlot似乎也是如此.

Aus*_*ips 53

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

虽然PyQt4允许任何Python可调用在连接信号时用作插槽,但有时需要将Python方法明确标记为Qt插槽并为其提供C++签名.PyQt4提供了pyqtSlot()函数装饰器来完成这项工作.

将信号连接到装饰的Python方法还具有减少内存使用量的优势,并且速度稍快.

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

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

  • 感谢您提供简洁而完整的答案。我一直主要依赖 PySide 文档,因为这是我正在使用的库,但我看到了对 PyQt 文档进行排序的优势。 (3认同)
  • @simon Qt是用C++和信号/插槽机制实现的,所以在某些时候,即使你定义了自己的信号/插槽,它们也会遍历底层的C++实现. (3认同)
  • 我并不完全理解这个答案 - 如果我正在定义自己的插槽(或者覆盖内置的插槽),为什么我需要一个C++函数签名(没有C++函数......)? (2认同)
  • * 有时需要显式地将 Python 方法标记为 Qt 槽*。我想知道那些“有时”是什么,似乎文档作者不知道。例如,如果我使用 QThread,它是强制性的吗?如果没有那么什么时候。 (2认同)

Mar*_*ase 9

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

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


小智 6

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

派生类在PySide中接收错误线程中的信号(Qt/PyQt)

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