如何查找信号是否连接到任何设备

7
有没有一种方法可以判断信号是否已连接到函数?例如,我想知道signals.siSelectionChange是否已连接到任何内容。
signals.siSelectionChange.connect( self.SelAsSiAssets )
2个回答

11

你可以使用 QObject.receivers 来获取已连接的函数数量。我在一个QWidget窗口的closeEvent()中使用它,如下所示:

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

注意,参数字符串中的签名必须与真实签名匹配。


1
很遗憾,在PyQt5中不再起作用,请参见https://github.com/picotech/picosdk-python-examples/issues/2 - mike rodent
1
仍然在 PyQt5 下工作,只是语法有些不同:receiversCount = self.receivers(self.siSelectionChanged) if receiversCount > 0: self.sigChanged.disconnect() - ludwig

7
自从我尝试了用PyQt5,发现没有存在QtCore.SIGNAL。我尝试使用QObject的isSignalConnected方法。你将面临的另一个问题是,在PyQt5库中没有QMetaMethod.fromSignal
因此,我编写了一个getSignal函数。
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")))

输出:

is 'sigB' connected: False
sigB emitted!
is 'sigB' connected: True

干得好。这里至少有三件事不令人满意:1)PyQt5文档是错误的(没有fromSignal),2)当没有连接时,认为disconnect应该抛出RuntimeError(甚至是Exception)毫无意义,3)我不明白为什么这些QObject方法(例如isSignalConnected)中有这么多实例方法,而它们应该是静态方法:不够优雅。 - mike rodent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接