阅读Qt信号和插槽文档,新样式连接失败的唯一原因似乎是:“如果已经存在重复(相同的信号指向同一对象上完全相同的插槽),则连接将失败,连接将返回false”。
这意味着连接已经第一次成功,并且在使用Qt::UniqueConnection时不允许多个连接。
这是否意味着Qt-5风格的连接将永远成功?还有其他失败的原因吗?
发布于 2017-04-20 16:17:08
由于各种原因,新样式的connect仍然可能在运行时失败:
sender或receiver都是空指针。显然,这需要一个只能在运行时进行的检查。signals:部分中。当moc看到您的类定义时,它将生成包含该函数确实是信号的信息的一些元数据。因此,在运行时,将在表中查找传递给connect的指针,如果找不到指针,connect本身就会失败(因为您没有传递信号)。1. one is the TU containing moc-generated data (typically a `moc_class.cpp` file). In this TU there's the aforementioned table containing, amongst other things, pointers to the signals (which are just ordinary member functions).
2. is the TU where you actually invoke `connect(sender, &Sender::signal, ...)`, which generates the pointer that gets looked up in the table.现在,两个TUs可能在同一个应用程序中,或者一个在库中,另一个在应用程序中,或者在两个库中,等等;您的平台的ABI开始发挥作用。
理论上,在执行1时存储的指针与执行2时生成的指针相同。在实践中,我们发现没有发生这种情况(cf )。我之前报告的这个错误报告,在ARM上的旧版本的GNU生成的代码无法进行比较)。
对于Qt来说,这意味着禁用某些优化和/或将一些额外的标志传递到我们知道会发生的地方,并破坏用户软件。例如,在QT5.9中,除了-Bsymbolic*和x86-64之外,GCC不支持任何东西上的x86标志。
当然,这并不意味着我们已经找到并修复了所有可能的地方。新的编译器和更积极的优化可能会在将来再次触发这个错误,使得connect返回false,即使所有的东西都应该正常工作。
发布于 2017-04-20 09:23:45
是的,如果发送方或接收方都不是有效对象(例如nullptr),则可能会失败。
示例
QObject* obj1 = new QObject();
QObject* obj2 = new QObject();
// Will succeed
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater);
delete obj1;
obj1 = nullptr;
// Will fail even if it compiles
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater);发布于 2022-08-04 13:30:17
不要尝试注册指针类型。我用了宏
#define QT_REG_TYPE(T) qRegisterMetaType<T>(#T)对于指针类型CMyWidget*,这就是问题所在。使用该类型可以直接工作。
https://stackoverflow.com/questions/43487752
复制相似问题