[PyQt] Hijacking QtCore.connect, disconnect and emit

Carlos Scheidegger cscheid at sci.utah.edu
Thu Jul 12 23:19:31 BST 2007


> Qt has builtin callbacks for signal slot debugging.  I think you could use 
> python's ctypes module to create python callbacks that would work.  I don't 
> have much experience with ctypes or using Qt's callbacks, so I can't provide 
> any further details.

Thanks for the quick response. There is, in fact, QSignalSpy, but it doesn't
seem to be implemented in PyQt. Is there any reason for that?

In any case, I found a way around that. In case anyone is interested, here's
the final ugly solution:

_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

just call enableSignalDebugging(emitCall=foo) and spy your signals until
you're sick to your stomach :)

-carlos


More information about the PyQt mailing list