7

Is there a way to tell if a signal is already connected to a function?

i.e I want to see if signals.siSelectionChange is connected to anything

signals.siSelectionChange.connect( self.SelAsSiAssets )
Jay
  • 3,373
  • 6
  • 38
  • 55

2 Answers2

11

You can use QObject.receivers to get the count of connected functions. I used it as follows, in the closeEvent() of a QWidget, I use as window:

    receiversCount = self.receivers(QtCore.SIGNAL("siSelectionChanged()"))
    if receiversCount > 0:
        self.sigChanged.disconnect()

Note that the signature in the argument string must match the real signature.

this.myself
  • 2,101
  • 2
  • 22
  • 36
alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • 1
    No longer works in PyQt5, sadly, see https://github.com/picotech/picosdk-python-examples/issues/2 – mike rodent Nov 19 '21 at 17:49
  • Still working under PyQt5 with slightly other syntax: `receiversCount = self.receivers(self.siSelectionChanged) if receiversCount > 0: self.sigChanged.disconnect()` – ludwig May 22 '23 at 10:39
7

Since I tried this with PyQt5 and it appears that there does not exist a QtCore.SIGNAL. I tried it with the isSignalConnected method of the QObject. An other problem you will face with this option is that there is no QMetaMethod.fromSignal in the PyQt5 library.

As result I wrote a getSignal function.

from PyQt5.QtCore import QMetaMethod
from PyQt5.QtCore import QObject

def getSignal (oObject : QObject, strSignalName : str):
    oMetaObj = oObject.metaObject()
    for i in range (oMetaObj.methodCount()):
        oMetaMethod = oMetaObj.method(i)
        if not oMetaMethod.isValid():
            continue
        if oMetaMethod.methodType () == QMetaMethod.Signal and \
            oMetaMethod.name() == strSignalName:
            return oMetaMethod

    return None


from PyQt5.QtCore import pyqtSignal

if __name__ == "__main__":
    class A (QObject):
        sigB = pyqtSignal()
        def __init__ (self):
            super().__init__()

    oA = A ()

    print ("is 'sigB' connected:", oA.isSignalConnected (getSignal(oA, "sigB")))

    oA.sigB.connect (lambda : print("sigB emitted!"))
    oA.sigB.emit()

    print ("is 'sigB' connected:", oA.isSignalConnected (getSignal(oA, "sigB")))

Output:

is 'sigB' connected: False
sigB emitted!
is 'sigB' connected: True
leafar
  • 71
  • 1
  • 3
  • Well done. At least 3 things here are unsatisfactory: 1) the PyQt5 documentation is wrong (no `fromSignal`), 2) the idea that `disconnect` should throw a `RuntimeError` (or even an `Exception`) when there are no connections makes no sense, 3) I don't understand why so many of these `QObject` methods (e.g. `isSignalConnected`) are instance methods when they should be static methods: inelegant. – mike rodent Aug 15 '21 at 16:43