为啥我需要用 pyqtSlot 装饰连接的插槽?

Posted

技术标签:

【中文标题】为啥我需要用 pyqtSlot 装饰连接的插槽?【英文标题】:Why do I need to decorate connected slots with pyqtSlot?为什么我需要用 pyqtSlot 装饰连接的插槽? 【发布时间】:2016-10-30 04:07:47 【问题描述】:

我正在使用 pyqt5,我有几个方法使用类似于以下的代码连接:

self.progress.canceled.connect(self.cancel)

例如,self.cancel 是:

def cancel(self):
    self.timer.stop()

这段代码似乎在多种情况下都能正常工作,而无需使用pyqtSlot 装饰cancel 或对其进行任何特殊处理。

我的问题是:

    这样做我会失去什么? 需要pyqtSlot 的原因是什么?

【问题讨论】:

【参考方案1】:

pyqtSlot 的主要目的是允许定义多个不同的插槽重载,每个重载都有不同的签名。有时在进行跨线程连接时也可能需要它(请参阅this answer 以了解此类情况)。但是,这些用例相对较少,并且在大多数 PyQt 应用程序中根本不需要使用 pyqtSlot。信号可以连接到任何 python 可调用对象,无论它是否被装饰为插槽。

PyQt 文档还指出:

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

但是,在实践中,这种优势通常很小,并且经常会被其他因素所淹没。它对原始信号速度的影响非常小,在它开始对 CPU 负载或内存使用产生重大影响之前,有必要进行 数千次 的发射/连接。有关这些点的深入分析,请参阅@Schollii 的这篇代码项目文章:

PyQt5 signal/slot connection performance

【讨论】:

另外,(至少在PySide 中;不过,我认为PyQt 也是如此),如果你想发送,必须使用 slot 装饰器跨线程的信号数据。 @BrendanAbel。 PySide 或 PyQt 中的跨线程信号不需要它。唯一的例外是信号是否在将对象移动到另一个线程之前连接 - 但这只会影响 PyQt。这是我在上面的回答中提到的场景(有关更完整的解释,请参阅this other answer)。【参考方案2】:

另一个好处是当你为Qt-designer设计自定义小部件时,pyqtSlot修饰的方法可以在Signal/Slot Editor中选择,否则你需要编写代码。

【讨论】:

+1 指出了这一点,但很遗憾看到编辑器比解释器更受限制......奇怪的设计选择。 这在您开发设计器插件时非常重要,并且未公开的功能可能不容易被用户察觉。

以上是关于为啥我需要用 pyqtSlot 装饰连接的插槽?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中将 @pyqtSlot 装饰器与其他装饰器一起使用?

pyqt 按钮自动绑定到 on_..._clicked 函数,无需连接或 pyqtSlot

PyQt5 线程、信号和插槽。连接错误

按名称使用自动连接插槽

3. 使用装饰者设计模式创建数据库连接池

为啥我安装不了CTeX 中文套装 2.2.4 nbsp