当QT-5失败时,连接失败

  • 本文关键字:失败 连接 QT-5 qt qt5
  • 更新时间 :
  • 英文 :


读取QT Signal&插槽文档,似乎新样式连接失败的唯一原因是:"如果已经有重复(与同一对象上完全相同的插槽完全相同的信号(,则连接将失败,连接将返回false"

这意味着连接已经是第一次成功,并且在使用QT :: iniqueConnection时不允许多连接。

这是否意味着QT-5样式连接将永远成功?还有其他故障原因吗?

由于各种原因,新风格的connect仍然可以在运行时失败:

  • senderreceiver是无效的指针。显然,这需要只能在运行时发生的检查。
  • 您为信号指定的PMF实际上不是信号。缺乏适当的C 反射功能,您可以在编译时所能做的就是检查信号是发件人类的非静态成员函数。

    但是,这还不足以使其成为一个信号:它也需要在您的类定义中的signals:部分中。当moc看到您的类定义时,它将生成一些元数据,其中包含该功能确实是信号的信息。因此,在运行时,将指针传递给connect的表格在表格中,如果找不到指针,则connect本身将失败(因为您没有通过信号(。

  • 上一个点的检查实际上需要指针与成员函数之间的比较。这是一个特别棘手的,因为它通常会涉及不同的tu:

    1. 一个是包含MOC生成数据的TU(通常是moc_class.cpp文件(。在此图中,有上述表包含信号的指针(这只是普通的成员函数(。
    2. 是您实际调用connect(sender, &Sender::signal, ...)的TU,它会生成桌子上抬头的指针。

    现在,两个tus可能在同一应用程序中,或者一个可能在图书馆中,另一个在您的应用程序中,或者在两个库中,等等。您平台的ABI开始发挥作用。

    从理论上讲,执行1.时存储的指针与执行2时产生的指针相同;在实践中,我们发现了这种情况没有发生的情况(请参阅我一段时间以前报告的此错误报告,其中较旧版本的gnu ld在ARM生成的代码上未能进行比较(。

    对于QT,这意味着禁用某些优化和/或将一些额外标志传递给我们知道发生并破坏用户软件的地方。例如,从QT 5.9开始,除X86和X86-64以外,GCC上的-Bsymbolic*标志没有支持。

    当然,这并不意味着我们已经找到并修复了所有可能的地方。新的编译器和更具侵略性的优化可能会在将来再次触发此错误,使connect返回false,即使一切都应该工作。

是的,如果发件人或接收者不是有效的对象(例如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);

不要尝试注册指针类型。我使用了宏

#define QT_REG_TYPE(T) qRegisterMetaType<T>(#T)

使用指针类型的cmywidget*,这就是问题所在。使用直接工作的类型。

不,它并不总是成功。文档在此处给出一个示例connect将返回false,因为信号不应包含变量名称。

// WRONG
QObject::connect(scrollBar, SIGNAL(valueChanged(int value)),
             label, SLOT(setNum(int value)));

最新更新