我目前正在将一个巨大的项目从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:错误:对不完整类型"QStaticAssertFailure"应用"sizeof"无效枚举{Q_STATIC_ASSERT_PRIVATE_JOIN(Q_STATIC_ASSERT_result,COUNTER)=大小(QStaticAssertFailure)}^
\Qt5\5.2.1 \mingw48_32\include/QtCore/qglobal.h:686:47:注意:在宏'Q_STATIC_ASSERT'#define的扩展中Q_STATIC_ASSERT_X(条件,消息)Q_STATIC_ASSERT(条件)^
\Qt5\5.2.1 \mingw48_32\include/QtCore/qobject.h:520:注意:在宏'Q_STATIC_ASSERT_X'的扩展中Q_STATIC_ASSERT_X(Qt特权::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不可能是错误的,所以它一定是源代码的一部分。
第2版:我设法隔离了触发错误的行,显然编译输出提供的信息比我想象的要多,但它是如此"分离",以至于我认为这是一个警告,没有什么可做的。这是我的应用程序的代码。注释的两行是触发错误的行。对不起我的错误。
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*)[带有T=ISPSItem*]"的实例化:…………..\Qt5\5.2.1 \mingw48_32\include/QtCore/qvariant h:695:51:从"静态T"QtPrivate::QVariantValueHelper::object(const QVariant&)[带T=ISPS项目**'…………..\Qt5\5.2.1 \mingw48_32\include/QtCore/qvariant.h:101:37:从"static ReturnType QtPrivate::ObjectInvoker::invoke(Argument)[派生=Qt特权::QVariantValueHelper;参数=常量QVariant&;ReturnType=ISPSItem*]'……..\Qt5\5.2.1 \mingw48_32\include/QtCore/qvariant h:810:64:从'T qvariant_cast(const qvariant&)[with T=ISPSItem*]'中需要…………..\Qt5\5.2.1 \mingw48_32\include/QtCore/qvariant.h:38:从'T QVariant::value()const[with T=ISPSItem*]'中需要..\marssies\ispswidget.cpp:785:109:从这里开始需要第3版:我留下了这两行注释,并继续迁移应用程序,直到我在另一个文件中得到相同的错误,这是一行:
我在另一个.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*)
在获得了关于错误和触发错误的来源的大量信息后,我得出结论,根本原因可能是在QVariant中使用QObject
子类,尤其是在调用QVariant::value()
函数时。正如Qt文档所说:
如果QVariant包含指向从QObject派生的类型的指针,则T可以是任何QObject类型。如果存储在QVariant中的指针可以将qobject_cast设置为T,则返回该结果。否则为null返回指针请注意,这只适用于QObject子类其使用Q_OBJECT宏。
我相信,在这些类(ISPSItem
)声明中添加Q_OBJECT
宏将解决问题。
在使用ISPSItem作为QVariant cast之前添加此项:
Q_DECLARE_METATYPE(ISPSItem)
为了解决需要将类添加到QMetaType的问题,宏会执行此操作。
Q_DECLARE_METATYPE(Type)
只要QMetaType提供公共默认构造函数、公共复制构造函数和公共析构函数,此宏就会使类型type为QMetaType所知。需要将类型type用作QVariant中的自定义类型。
好看!
当我更改信号变量类型时,我看到了这个问题,但同时我忘记了更改插槽描述。例如我有一个信号槽:这是signal->setResult(bool-res);这是slot->setResult(bool-res){}
I更改信号的类型signal->setResult(QString-res);slot->setResult(bool-res)/////当我忘记更改此资产时,此EXP