I want to debug event handling code and would like to convert QEvent::Type
enum's value to a human-readable string. QEvent
has a Q_GADGET
macro, so presumably there's a way of pulling that off?
我想调试事件处理代码,并希望将QEvent :: Type枚举值转换为人类可读的字符串。 QEvent有一个Q_GADGET宏,所以可能有一种方法可以解决这个问题吗?
2 个解决方案
#1
21
Recent versions of Qt do the right thing when outputting events to the debug stream, so the below isn't neccessary. If you get an error similar to warning C4273: 'operator <<' : inconsistent dll linkage
, it means that your version of Qt already supports this without need for the code below.
最新版本的Qt在将事件输出到调试流时做了正确的事情,因此下面不是必需的。如果你得到类似于警告C4273的错误:'operator <<':不一致的dll链接,这意味着你的Qt版本已经支持这个,而不需要下面的代码。
The Q_GADGET
macro adds a QMetaObject staticMetaObject
member to the class. The static metaobject's definition is generated by moc, and it - in the case of QEvent
- contains the enumeration information.
Q_GADGET宏将QMetaObject staticMetaObject成员添加到类中。静态元对象的定义由moc生成,而在QEvent的情况下,它包含枚举信息。
Below is an example of how to leverage that to give a more reasonable QDebug
output of events.
下面是如何利用它来提供更合理的QDebug事件输出的示例。
#include <QEvent>
#include <QMetaEnum>
#include <QDebug>
/// Gives human-readable event type information.
QDebug operator<<(QDebug str, const QEvent * ev) {
static int eventEnumIndex = QEvent::staticMetaObject
.indexOfEnumerator("Type");
str << "QEvent";
if (ev) {
QString name = QEvent::staticMetaObject
.enumerator(eventEnumIndex).valueToKey(ev->type());
if (!name.isEmpty()) str << name; else str << ev->type();
} else {
str << (void*)ev;
}
return str.maybeSpace();
}
Use example:
使用示例:
void MyObject::event(QEvent* ev) {
qDebug() << "handling an event" << ev;
}
#2
2
Q_GADGET and Q_ENUM can be combined to get the following template:
可以组合Q_GADGET和Q_ENUM来获取以下模板:
template<typename EnumType>
QString ToString(const EnumType& enumValue)
{
const char* enumName = qt_getEnumName(enumValue);
const QMetaObject* metaObject = qt_getEnumMetaObject(enumValue);
if (metaObject)
{
const int enumIndex = metaObject->indexOfEnumerator(enumName);
return QString("%1::%2::%3").arg(metaObject->className(), enumName, metaObject->enumerator(enumIndex).valueToKey(enumValue));
}
return QString("%1::%2").arg(enumName).arg(static_cast<int>(enumValue));
}
Example:
例:
void MyObject::event(QEvent* ev)
{
qDebug() << ToString(ev->type());
}
#1
21
Recent versions of Qt do the right thing when outputting events to the debug stream, so the below isn't neccessary. If you get an error similar to warning C4273: 'operator <<' : inconsistent dll linkage
, it means that your version of Qt already supports this without need for the code below.
最新版本的Qt在将事件输出到调试流时做了正确的事情,因此下面不是必需的。如果你得到类似于警告C4273的错误:'operator <<':不一致的dll链接,这意味着你的Qt版本已经支持这个,而不需要下面的代码。
The Q_GADGET
macro adds a QMetaObject staticMetaObject
member to the class. The static metaobject's definition is generated by moc, and it - in the case of QEvent
- contains the enumeration information.
Q_GADGET宏将QMetaObject staticMetaObject成员添加到类中。静态元对象的定义由moc生成,而在QEvent的情况下,它包含枚举信息。
Below is an example of how to leverage that to give a more reasonable QDebug
output of events.
下面是如何利用它来提供更合理的QDebug事件输出的示例。
#include <QEvent>
#include <QMetaEnum>
#include <QDebug>
/// Gives human-readable event type information.
QDebug operator<<(QDebug str, const QEvent * ev) {
static int eventEnumIndex = QEvent::staticMetaObject
.indexOfEnumerator("Type");
str << "QEvent";
if (ev) {
QString name = QEvent::staticMetaObject
.enumerator(eventEnumIndex).valueToKey(ev->type());
if (!name.isEmpty()) str << name; else str << ev->type();
} else {
str << (void*)ev;
}
return str.maybeSpace();
}
Use example:
使用示例:
void MyObject::event(QEvent* ev) {
qDebug() << "handling an event" << ev;
}
#2
2
Q_GADGET and Q_ENUM can be combined to get the following template:
可以组合Q_GADGET和Q_ENUM来获取以下模板:
template<typename EnumType>
QString ToString(const EnumType& enumValue)
{
const char* enumName = qt_getEnumName(enumValue);
const QMetaObject* metaObject = qt_getEnumMetaObject(enumValue);
if (metaObject)
{
const int enumIndex = metaObject->indexOfEnumerator(enumName);
return QString("%1::%2::%3").arg(metaObject->className(), enumName, metaObject->enumerator(enumIndex).valueToKey(enumValue));
}
return QString("%1::%2").arg(enumName).arg(static_cast<int>(enumValue));
}
Example:
例:
void MyObject::event(QEvent* ev)
{
qDebug() << ToString(ev->type());
}