3

我试图弄清楚为什么要使用 pyqt 信号/插槽而不是直接调用类方法。

这是一个简单的代码片段,说明了我的看法:

from PyQt4 import QtGui, QtCore

class Simple_signal(QtCore.QObject):
    single_signal = QtCore.pyqtSignal()
    double_signal = QtCore.pyqtSignal()

    def __init__(self):
        super().__init__()
        # Connect one signal to one slot
        self.single_signal.connect(self.handle_signal_choice1)

        # Connect another signal to two slots
        self.double_signal.connect(self.handle_signal_choice1)
        self.double_signal.connect(self.handle_signal_choice2)

        # Connect to one method
        self.method = self.handle_signal_choice3

    def handle_signal_choice1(self):   
        print("Simple_signal - CHOICE1 received")

    def handle_signal_choice2(self):
        print("Simple_signal - CHOICE2 received")

    def handle_signal_choice3(self):
        print("Simple_signal - CHOICE3 received")

if __name__ == "__main__":
    simple_signal = Simple_signal()
    print('Calling choice1 via single_signal')
    simple_signal.single_signal.emit()

    print('Calling choice1 and choice2 via double_signal')
    simple_signal.double_signal.emit()

    print('Calling choice3 via class method')
    simple_signal.method()

信号的一个直接优势似乎是:将信号附加到两个插槽相当容易。但是,我也可以使用方法示例来做到这一点,而不用大惊小怪。

方法示例似乎比信号/槽示例获得更好的 CPU 时间结果(即更快),但如果您需要从一个信号调用多个槽,则可能会失去该优势。

在我看来,调用该方法比弄乱信号/插槽设置更干净。

两者都可以在 QWidgets 中使用。

我是否需要一个更复杂的情况,其中信号/插槽是比直接调用方法更好的选择?

谢谢。

编辑: 对每种方法消耗的时间感到好奇,我做了一些时间检查。

将这些 timeit 行添加到代码中,并将原始代码(即在 handle_signal_choice1 中)中的每个 'print' 行替换为“pass”,这样打印到 shell 不会减慢速度。

result=timeit.timeit('simple_signal.single_signal.emit()', 'from __main__ import simple_signal', number=10000)
print('Calling choice1 via single_signal')
print('timeit says : ', result)

result=timeit.timeit('simple_signal.double_signal.emit()', 'from __main__ import simple_signal', number=10000)
print('Calling choice1 and choice2 via double_signal')
print('timeit says : ', result)

result=timeit.timeit('simple_signal.method()', 'from __main__ import simple_signal', number=10000)
print('Calling choice3 via method')
print('timeit says : ', result)

这给了我以下结果,这支持了我对单个方法调用比单个信号/插槽更快的怀疑:

Now start timeit tests
Calling choice1 via single_signal  
timeit says :  0.010595089312688225
Calling choice1 and choice2 via double_signal 
timeit says :  0.014604222516910098
Calling choice3 via method
timeit says :  0.0016033988748859057

如果您通过信号/插槽而不是方法驱动套接字事件循环,那将有很大的不同。单击按钮应该无关紧要。

4

1 回答 1

4

使用信号和插槽的原因不是速度,而是松耦合。使用信号和槽可以更好地重用。有一篇很好的论文讨论了动机和好处。它确实增加了一些间接性,但它非常值得,恕我直言。

于 2013-04-06T08:02:54.513 回答