How to get human-readable event type from QEvent?

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?

Answers


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.

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.

Below is an example of how to leverage that to give a more reasonable QDebug output of events.

#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;
}

Q_GADGET and Q_ENUM can be combined to get the following template:

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());
}

Need Your Help

Which SCM system for Xcode?

cocoa xcode svn macos version-control

I am developing an application for the Mac as a small team (me + another person) effort. We are located in different cities, and have started to see the need for solid source control management.

CMake... ccmake or cmake?

cmake

What is the difference between cmake and ccmake? I have the Ubuntu package cmake installed, and on my Windows computer, I have the installer from the website, but neither have the command ccmake