我已经将自己注入到 Qt 应用程序中,并且试图找出给定插槽连接到的信号,但找不到任何有关执行此操作的信息。有开箱即用的机制吗?如果是这样,这是否暴露给 QtScript?(如果没有,我可以很容易地包装它。)
如果没有这样的机制,添加它的最佳方法是什么?我无法在简单挂钩之外操作现有应用程序,但我可以挂钩 QObject::connect 并自己存储连接,只是不确定这是否是最好的方法。
我已经将自己注入到 Qt 应用程序中,并且试图找出给定插槽连接到的信号,但找不到任何有关执行此操作的信息。有开箱即用的机制吗?如果是这样,这是否暴露给 QtScript?(如果没有,我可以很容易地包装它。)
如果没有这样的机制,添加它的最佳方法是什么?我无法在简单挂钩之外操作现有应用程序,但我可以挂钩 QObject::connect 并自己存储连接,只是不确定这是否是最好的方法。
我认为 Qt 存储给定信号连接到的插槽,因此当您发出它时,所有接收器都会被调用,因此您可以访问接收器列表:
出于调试目的,您有:
无效 QObject::dumpObjectInfo ()
将此对象的有关信号连接等的信息转储到调试输出。
该函数对调试很有用,但如果库已在发布模式下编译(即没有调试信息),则不会执行任何操作。
并且连接了信号的插槽列表:
int QObject::receivers ( const char * signal ) const [受保护]
返回连接到信号的接收器数量。
metaObject() 为您提供插槽的 QMetaMethod,但它没有关于其连接的信息。
但是,如果您知道对象,则可以检查所有信号(使用元对象,测试信号的方法类型)并使用槽接收器()为您构建反向索引。
如果不保存 Qt 的内部互斥体/信号量,就无法安全地迭代信号槽连接列表。信号和插槽可以随时来来去去,所以充其量你会得到一个不能保证正确的列表 - 因此无用。
无论你做什么钩子QObject::connect
本身都是不够的。您从此类挂钩中获得的数据将遭受以下影响:
您可能拥有指向在您尝试访问它们时已被删除的对象的指针。您可以使用 来缓解这种情况QPointer
,但这仅适用于运行代码的线程中的对象。您需要将对象注入其他线程以在那里收集对象列表。
您可能拥有不再存在的连接。即使挂钩QObject::disconnect
也不够,因为当对象不再存在时连接会被删除。
您面临的问题非常复杂,任何强大的解决方案都不仅限于“挂钩” QObject::connect
。
唉,您还没有说明为什么需要附加到插槽的信号列表。它的目的是什么?
在深入研究了 Qt 代码库和文档(我从这里和其他地方得到了很多有用的提示)之后,我最终决定挂钩 QObject::connect (静态重载)。为什么?好吧,其他解决方案要求您知道哪些对象提供了信号,深入研究私有字段,或者必须拥有 Qt 的调试版本。最后,挂钩 QObject::connect 为您提供了应用程序中连接的所有内容,您可以轻松地映射回插槽。