我目前正在将一个巨大的项目从Qt 4.x迁移到5.2.1,一直都很好,直到这个错误,我发现它非常令人困惑,因为它位于Qt文件,我相信必须应用解决方案在其他地方,而不是位于5.2.1 \ mingw48_32 \ include / QtCore / qglobal.h的qglobal.h中。 错误必定发生在其他地方。
继承错误:
.......... \ Qt5 \ 5.2.1 \ mingw48_32 \ include / QtCore / qglobal.h :681:85:错误:无效的应用' sizeof'到不完整类型'QStaticAssertFailure' 枚举{Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER )= sizeof(QStaticAssertFailure)} ^
.......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qglobal.h中:686:47: 注意:扩展宏'Q_STATIC_ASSERT'#define Q_STATIC_ASSERT_X(条件,消息)Q_STATIC_ASSERT(条件) ^
.......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject.h:520:5: 注意:扩展宏'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X(QtPrivate :: HasQ_OBJECT_Macro ::值, ^
这是qglobal.h中的一段代码
// Intentionally undefined
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
#ifdef __COUNTER__
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#else
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#endif /* __COUNTER__ */
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
#endif
我已经尝试了所有的东西并且已经研究了所有这些,但没有找到合适的解决方案。我整天浪费在这段恼人的代码中。我希望有人能够对此事有所了解。
非常感谢。
编辑:我搜索了包含qglobal.h的所有文档,但没有一个使用任何断言函数,所以我不知道什么可能触发这样的错误。没有办法qglobal.h是错的,所以它必须是源代码的东西。EDIT2:我设法隔离了触发错误的行,显然编译输出提供了比我想象的更多的信息,但它是如此“分开”,我认为这是一个警告,无所事事。这是我的应用程序的代码。两条注释行是触发错误的行。抱歉我的错误。
bool ISPSModel::removeGraphics(GraphicsPrimitive* _gtr) {
for (int _i = 0; _i < ispss.size(); _i++) {
for (int _j = 0; _j < ispss[_i]->graphicsObjects.size(); _j++) {
if (ispss[_i]->graphicsObjects[_j] != _gtr)
continue;
if (ispss[_i]->graphicsObjects.contains(_gtr)) {
//beginRemoveRows(indexFromItem(ispss[_i]->m_item), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row(), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row());
//_gtr->getData(DATA_ROLE).value<ISPSItem*>()->remove();
ispss[_i]->removeGraphics(ispss[_i]->graphicsObjects[_j]);
endRemoveRows();
return true;
}
}
}
return false;
}
这部分导致错误:
value<ISPSItem*>()
下面是我忽略的编译错误的另一部分,以防它可以提供帮助:
.......... \ Qt5 \ 5.2.1 \ mingw48_32 \ include / QtCore / qobject.h:In 实例化'T qobject_cast(QObject *)[with T = ISPSItem *]': .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:695:51: 需要'静态T QtPrivate :: QVariantValueHelper :: object(const QVariant&amp;)[with T = ISPSItem *]” .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:101:37: 'static ReturnType QtPrivate :: ObjectInvoker :: invoke(Argument)[with Derived = QtPrivate :: QVariantValueHelper; Argument = const QVariant&amp ;; ReturnType = ISPSItem *]' .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:810:64: 需要'T qvariant_cast(const QVariant&amp;)[与T = ISPSItem *]' .......... \ QT5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant.h:348:36: 来自'T QVariant :: value()const [with T = ISPSItem *]' .. \ marssies \ ispswidget.cpp:785:109:从这里需要 EDIT3: 我留下了那两行注释并继续迁移应用程序,直到我在另一个文件中得到相同的错误,这就是这一行:
我在另一个.cpp中使用不同的类获得相同的错误,但它们的共同点是.value<Type>();
Notify* _n = ui.notifyBox->model()->data(index, Qt::UserRole).value<Notify*>();
所以肯定是.value<Type>();
会引发错误,现在唯一剩下的就是找到解决方法。
这是ISPSItem的对象,如果它有用:
class ISPSItem : public QObject {
public:
enum Level {ROOT_LEVEL = 1,
ISPS_LEVEL,
GRAPHICS_LEVEL
} level;
ISPSItem(ISPSItem* = NULL, Level = ROOT_LEVEL, int = -1);
~ISPSItem();
ISPSItem* parentItem() {return _parentItem;}
ISPSItem* child(int);
void appendChild(ISPSItem*);
void insertChild(ISPSItem*, int);
int childCount() const {return children.size();}
int row() const;
int newNodeRow(Level);
void remove();
private:
QList<ISPSItem*> children;
ISPSItem* _parentItem;
void remove(ISPSItem*);
};
Q_DECLARE_METATYPE(ISPSItem*)
答案 0 :(得分:7)
在获得有关错误的大量信息以及触发它的源代码后,我得出结论,根本原因可能是在QVariant中使用QObject
子类,尤其是在调用QVariant::value()
函数时。正如Qt博士所说:
如果QVariant包含指向从QObject派生的类型的指针,那么 T可以是任何QObject类型。如果存储在QVariant中的指针可以 将qobject_cast改为T,然后返回该结果。否则为null 返回指针。 请注意,这仅适用于QObject子类 它使用Q_OBJECT宏。
我相信,将Q_OBJECT
宏添加到这些类(ISPSItem
)声明将解决问题。
答案 1 :(得分:2)
当我更改信号变量类型时我看到了这个问题,但同时我忘了更改插槽描述。例如; 我有一个信号槽:这是信号 - &gt; setResult(bool res); 这是插槽 - &gt; setResult(bool res){}
我改变信号的类型信号 - &gt; setResult(QString res); 插槽 - &gt; setResult( bool res ); ///// 当我忘记更改此评估此
答案 2 :(得分:2)
在将ISPSItem用作QVariant转换之前添加此项:
Q_DECLARE_METATYPE(ISPSItem)
要解决问题,您需要将类添加到QMetaType,宏就可以。
Q_DECLARE_METATYPE(Type)
只要它提供了一个公共默认构造函数,一个公共复制构造函数和一个公共析构函数,这个宏就会使QMetaType知道类型Type。需要在QVariant中使用Type类型作为自定义类型。
好看!