Qt: Defining a custom event type

2019-02-03 04:48发布

I have created a custom event in my Qt application by subclassing QEvent.

class MyEvent : public QEvent
{
  public:
    MyEvent() : QEvent((QEvent::Type)2000)) {}
    ~MyEvent(){}
}

In order to check for this event, I use the following code in an event() method:

if (event->type() == (QEvent::Type)2000)
{
  ...
}

I would like to be able to define the custom event's Type somewhere in my application so that I don't need to cast the actual integer in my event methods. So in my event() methods I'd like to be able to do something like

if (event->type() == MyEventType)
{
  ...
}

Any thoughts how and where in the code I might do this?

标签: c++ qt qt4
3条回答
Luminary・发光体
2楼-- · 2019-02-03 05:25

For convenience, you can use the QEvent::registerEventType() static function to register and reserve a custom event type for your application. Doing so will allow you to avoid accidentally re-using a custom event type already in use elsewhere in your application.

Example:

class QCustomEvent : public QEvent
{
public:
    QCustomEvent() : QEvent(QCustomEvent::type())
    {}

    virtual ~QCustomEvent()
    {}

    static QEvent::Type type()
    {
        if (customEventType == QEvent::None)
        {
            int generatedType = QEvent::registerEventType()
            customEventType = static_cast<QEvent::Type>(generatedType);
        }
        return customEventType;
    }

private:
    static QEvent::Type customEventType;
};

QEvent::Type QCustomEvent::customEventType = QEvent::None;
查看更多
爷、活的狠高调
3楼-- · 2019-02-03 05:30

The idiomatic way of dealing with such problems is to create a template wrapper class, leveraging CRTP. For each custom event type, such template represents a new type, thus a separate staticType() member exists for each type, returning its unique registered type.

Below I give three ways of identifying types:

  1. By staticType() -- this is only useful within an invocation of the application, and is the type to be used with QEvent. The values are not guaranteed to stay the same between invocations of an application. They do not belong in durable storage, like in a log.

  2. By localDurableType() -- those will persist between invocations and between recompilations with the same compiler. It saves manual definition of durableType() method when defining complex events.

  3. By durableType() -- those are truly cross platform and will be the same unless you change the event class names within your code. You have to manually define durableType() if you're not using the NEW_QEVENT macro.

Both localDurableType() and durableType() differ betwen Qt 4 and 5 due to changes to qHash.

You use the header in either of two ways:

#include "EventWrapper.h"

class MyComplexEvent : public EventWrapper<MyComplexEvent> {
   // An event with custom data members
   static int durableType() { return qHash("MyEvent"); }
   ...
};

NEW_QEVENT(MySimpleEvent) // A simple event carrying no data but its type.

EventWrapper.h

#ifndef EVENTWRAPPER_H
#define EVENTWRAPPER_H

#include <QEvent>
#include <QHash>

template <typename T> class EventWrapper : public QEvent {
public:
   EventWrapper() : QEvent(staticType())) {}
   static QEvent::Type staticType() {
      static int type = QEvent::registerEventType();
      return static_cast<QEvent::Type>(type);
   }
   static int localDurableType() {
      static int type = qHash(typeid(T).name());
      return type;
   }
};

#define NEW_QEVENT(Name) \
   class Name : public EventWrapper< Name > \
   { static int durableType() { \
       static int durable = qHash(#Name); return durable; \
     } };

#endif // EVENTWRAPPER_H
查看更多
Evening l夕情丶
4楼-- · 2019-02-03 05:31

If the event-type identifies your specific class, i'd put it there:

class MyEvent : public QEvent {
public:
    static const QEvent::Type myType = static_cast<QEvent::Type>(2000);
    // ...
};

// usage:
if(evt->type() == MyEvent::myType) {
    // ...
}
查看更多
登录 后发表回答