Как получить читаемый человеком тип события из QEvent?
Я хочу отладить код обработки событий и хотел бы преобразовать QEvent::Type
Значение enum для удобочитаемой строки. QEvent
имеет Q_GADGET
макрос, так что, по-видимому, есть способ справиться с этим?
2 ответа
Последние версии Qt делают правильные вещи при выводе событий в поток отладки, поэтому приведенное ниже не является обязательным. Если вы получаете сообщение об ошибке, похожее на warning C4273: 'operator <<' : inconsistent dll linkage
, это означает, что ваша версия Qt уже поддерживает это без необходимости в приведенном ниже коде.
Q_GADGET
макрос добавляет QMetaObject staticMetaObject
член класса. Определение статического метаобъекта генерируется moc, а это - в случае QEvent
- содержит информацию о перечислении.
Ниже приведен пример того, как использовать это, чтобы дать более разумный 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();
}
Пример использования:
void MyObject::event(QEvent* ev) {
qDebug() << "handling an event" << ev;
}
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));
}
Пример:
void MyObject::event(QEvent* ev)
{
qDebug() << ToString(ev->type());
}