I am currently migrating a huge project from Qt 4.x to 5.2.1, Everything has been rather good until this error, which I find incredibly confusing because its located at the Qt files, and I believe the solution must be applied somewhere else, not in the qglobal.h located at 5.2.1\mingw48_32\include/QtCore/qglobal.h. The error must be happening somewhere else.
我正在从qt4迁移一个庞大的项目。x到5.2.1,在这个错误之前,一切都很好,我觉得非常混乱,因为它位于Qt文件中,我认为解决方案必须应用于其他地方,而不是qglobal。h位于5.2.1 \ mingw48_32 \包括/ QtCore / qglobal.h。错误必须发生在其他地方。
Heres the error:
这是错误的:
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:681:85: error: invalid application of 'sizeof' to incomplete type 'QStaticAssertFailure' enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER) = sizeof(QStaticAssertFailure)} ^
.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qglobal。h:681:85:错误:将“sizeof”应用于不完全类型的QStaticAssertFailure' enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER) = sizeof(QStaticAssertFailure)}。
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:686:47: note: in expansion of macro 'Q_STATIC_ASSERT' #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) ^
.......... \ 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\include/QtCore/qobject.h:520:5: note: in expansion of macro 'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, ^
.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject。h:520:5:注意:在宏'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X的扩展(QtPrivate::HasQ_OBJECT_Macro::Value,。
Here's the piece of code in qglobal.h
这是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
I have tried everything and have researched all about it, but didnt find a proper solution. I have wasted all day in this annoying piece of code. I hope someone can shed some light on the matter.
我已经试过了所有的方法,但都没有找到合适的解决方案。我在这恼人的代码中浪费了一整天。我希望有人能阐明这件事。
Thankyou very much.
非常谢谢。
EDIT: I searched for all the documents that included qglobal.h, but none of them make use of any assert funcion, so I dont know what could be triggering such error. Theres no way that the qglobal.h is wrong, so it must be something of the source code.
编辑:我搜索了所有包含qglobal的文档。h,但是他们都没有使用任何断言,所以我不知道是什么触发了这样的错误。qglobal是不可能的。h是错误的,所以它一定是源代码。
EDIT2: I managed to isolate the lines that trigger the error, apparently the compilation output gave more information than I thought, but it was so 'separated' that I thought it was a warning and had nothing to do. Here is the code from my application. The two commented lines are the ones that trigger the error. Sorry for my mistake.
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;
}
Its this part the one that causes the error:
它的这一部分导致了错误:
value<ISPSItem*>()
Heres the other part of the compilation error that I had ignored, in case it can help:
这是我忽略的编译错误的另一部分,如果它能提供帮助的话:
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qobject.h: In instantiation of 'T qobject_cast(QObject*) [with T = ISPSItem*]': ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:695:51: required from 'static T QtPrivate::QVariantValueHelper::object(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:101:37: required from 'static ReturnType QtPrivate::ObjectInvoker::invoke(Argument) [with Derived = QtPrivate::QVariantValueHelper; Argument = const QVariant&; ReturnType = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:810:64: required from 'T qvariant_cast(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:348:36: required from 'T QVariant::value() const [with T = ISPSItem*]' ..\marssies\ispswidget.cpp:785:109: required from here EDIT3: I left those 2 lines commented and kept migrating the application, until I got the same error in another file, this is the line:
.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qobject。h:在实例化的“T qobject_cast(QObject*)[与T = ISPSItem*]”中:“”\Qt5\5.2.1\mingw48_32\包括/QtCore/qvariant。h:695:51: QVariantValueHelper::object(const qvariant&) [with T = ISPSItem*]'…\Qt5\5.2.1\mingw48_32\包括/QtCore/qvariant。h:101:37:要求从静态ReturnType QtPrivate::调用(参数)[与派生= QtPrivate::QVariantValueHelper;参数= const QVariant&;ReturnType = ISPSItem *]“.......... \ Qt5 \ 5.2.1 \ mingw48_32 \包括/ QtCore / qvariant。h:810:64:要求从T qvariant_cast(const qvariant&) [with 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:需要从这里编辑3:我离开了这两行注释并继续迁移应用程序,直到我在另一个文件中得到相同的错误,这是一行:
Im getting the same error in another .cpp using a different class, but what they have in common is the .value<Type>();
我在另一个.cpp中使用不同的类得到相同的错误,但是它们的共同点是。value
Notify* _n = ui.notifyBox->model()->data(index, Qt::UserRole).value<Notify*>();
So definitely its the .value<Type>();
what throws the error, now the only thing left is to find a way around it.
因此,它的。value <类型> ();是什么导致了错误,现在唯一剩下的就是找到一种绕过它的方法。
Here is the object ISPSItem in case its useful:
这里有一个对象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*)
3 个解决方案
#1
6
After getting much information about the error and the sources that trigger it I conclude, that the root cause could be in using QObject
subclasses in QVariant, especially when calling QVariant::value()
function. As Qt docs say:
在获得关于错误和触发它的源的大量信息之后,我得出结论,根本原因可能是在QVariant中使用QObject子类,特别是在调用QVariant::value()函数时。Qt文档说:
If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise a null pointer is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.
如果QVariant包含一个指向来自QObject的类型的指针,那么T可能是任何QObject类型。如果在QVariant中存储的指针可以是qobject_cast到T,则返回该结果。否则将返回空指针。注意,这只适用于使用Q_OBJECT宏的QObject子类。
I believe, that adding Q_OBJECT
macro to these classes (ISPSItem
) declaration will solve the problem.
我相信,将Q_OBJECT宏添加到这些类(ISPSItem)声明将解决这个问题。
#2
2
I see this problem when I change signals variable type but at the same time I forgot changing slots descriptions.For example; I have a signal slot : this is signal-> setResult(bool res); this is slot -> setResult(bool res){}
当我改变信号变量类型时,我看到这个问题,但同时我忘记了改变槽的描述。例如;我有一个信号槽:这是信号-> setResult(bool res);这是槽-> setResult(bool res){}
I change signal's type signal -> setResult(QString res); slot -> setResult(bool res); /////WHEN I FORGOT CHANGING THIS ASSERT THIS EXP
我改变信号的类型信号-> setResult(QString res);槽- > setResult(bool res);///// ///// ///// ///// ///// ///// ///// ///// //
#3
2
Add this before you use ISPSItem as a QVariant cast:
在你使用ISPSItem作为一个q变体类型之前添加这个:
Q_DECLARE_METATYPE(ISPSItem)
To solve the problem you need to add your class to QMetaType, the macro do that.
要解决这个问题,您需要将类添加到QMetaType中,宏就会这样做。
Q_DECLARE_METATYPE(Type)
This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.
这个宏让QMetaType知道类型类型,只要它提供公共默认构造函数、公共复制构造函数和公共析构函数。在QVariant中,需要使用类型类型作为自定义类型。
Good look!
不错看!
#1
6
After getting much information about the error and the sources that trigger it I conclude, that the root cause could be in using QObject
subclasses in QVariant, especially when calling QVariant::value()
function. As Qt docs say:
在获得关于错误和触发它的源的大量信息之后,我得出结论,根本原因可能是在QVariant中使用QObject子类,特别是在调用QVariant::value()函数时。Qt文档说:
If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise a null pointer is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.
如果QVariant包含一个指向来自QObject的类型的指针,那么T可能是任何QObject类型。如果在QVariant中存储的指针可以是qobject_cast到T,则返回该结果。否则将返回空指针。注意,这只适用于使用Q_OBJECT宏的QObject子类。
I believe, that adding Q_OBJECT
macro to these classes (ISPSItem
) declaration will solve the problem.
我相信,将Q_OBJECT宏添加到这些类(ISPSItem)声明将解决这个问题。
#2
2
I see this problem when I change signals variable type but at the same time I forgot changing slots descriptions.For example; I have a signal slot : this is signal-> setResult(bool res); this is slot -> setResult(bool res){}
当我改变信号变量类型时,我看到这个问题,但同时我忘记了改变槽的描述。例如;我有一个信号槽:这是信号-> setResult(bool res);这是槽-> setResult(bool res){}
I change signal's type signal -> setResult(QString res); slot -> setResult(bool res); /////WHEN I FORGOT CHANGING THIS ASSERT THIS EXP
我改变信号的类型信号-> setResult(QString res);槽- > setResult(bool res);///// ///// ///// ///// ///// ///// ///// ///// //
#3
2
Add this before you use ISPSItem as a QVariant cast:
在你使用ISPSItem作为一个q变体类型之前添加这个:
Q_DECLARE_METATYPE(ISPSItem)
To solve the problem you need to add your class to QMetaType, the macro do that.
要解决这个问题,您需要将类添加到QMetaType中,宏就会这样做。
Q_DECLARE_METATYPE(Type)
This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.
这个宏让QMetaType知道类型类型,只要它提供公共默认构造函数、公共复制构造函数和公共析构函数。在QVariant中,需要使用类型类型作为自定义类型。
Good look!
不错看!