Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get human-readable event type from QEvent?

Tags:

qt

qevent

qgadget

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?

like image 715
Kuba hasn't forgotten Monica Avatar asked Mar 20 '14 14:03

Kuba hasn't forgotten Monica


2 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;
}
like image 99
Kuba hasn't forgotten Monica Avatar answered Oct 04 '22 01:10

Kuba hasn't forgotten Monica


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());
}
like image 33
Shank Avatar answered Oct 04 '22 01:10

Shank