PyQt&unittest测试信号和插槽

2024-09-30 18:17:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pyqt应用程序,我正在为它编写单元测试,它严重依赖于信号和插槽。为了正确地测试它,我必须检查是否发送了正确的信号。在

最好的办法是什么?我看到Qt库有一个QSignalSpy,但在PyQt中找不到任何引用。我能想到的唯一选择是模仿emit,例如

import testedmodule

def myemit(signal):
    ....

testedmodule.QObject.emit = myemit

但我希望有更好的方法。在

编辑:
我的模块是作为线程运行的,在这种情况下,在启动线程之后,重写实例的发出不再起作用,所以我更新了上面的代码以反映这一点。在


Tags: import应用程序信号def单元测试qt线程pyqt
3条回答

注意QSignalSpy在PyQt5中是available,即QtTest.QSignalSpy。在

这是我自己建议的更详细的版本,不一定是unittest的最佳解决方案,但我认为其他遇到这种情况的人会感兴趣:

Carlos Scheidegger在pyqt邮件列表(http://thread.gmane.org/gmane.comp.python.pyqt-pykde/9242/focus=9245)上发布

_oldConnect = QtCore.QObject.connect
_oldDisconnect = QtCore.QObject.disconnect
_oldEmit = QtCore.QObject.emit

def _wrapConnect(callableObject):
    """Returns a wrapped call to the old version of QtCore.QObject.connect"""
    @staticmethod
    def call(*args):
        callableObject(*args)
        _oldConnect(*args)
    return call

def _wrapDisconnect(callableObject):
    """Returns a wrapped call to the old version of QtCore.QObject.disconnect"""
    @staticmethod
    def call(*args):
        callableObject(*args)
        _oldDisconnect(*args)
    return call

def enableSignalDebugging(**kwargs):
    """Call this to enable Qt Signal debugging. This will trap all
    connect, and disconnect calls."""

    f = lambda *args: None
    connectCall = kwargs.get('connectCall', f)
    disconnectCall = kwargs.get('disconnectCall', f)
    emitCall = kwargs.get('emitCall', f)

    def printIt(msg):
        def call(*args):
            print msg, args
        return call
    QtCore.QObject.connect = _wrapConnect(connectCall)
    QtCore.QObject.disconnect = _wrapDisconnect(disconnectCall)

    def new_emit(self, *args):
        emitCall(self, *args)
        _oldEmit(self, *args)

    QtCore.QObject.emit = new_emit

只需调用enableSignalDebugging(emitCall=foo)并监视信号,直到 你肚子不舒服:)

你可以尝试连接一个插槽到你的信号,准备你的测试,然后打电话qApp.processEvents()让信号传播。但我不认为它100%可靠。在

遗憾的是QSignalSpy并不是PyQt的一部分。在

相关问题 更多 >