Qt: Defining a custom event type
I have created a custom event in my Qt application by subclassing QEvent.
class MyEvent : public QEvent
{
public:
MyEvent() : QEvent((QEvent::Type)2000))开发者_Go百科 {}
~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?
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) {
// ...
}
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;
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:
By
staticType()
-- this is only useful within an invocation of the application, and is the type to be used withQEvent
. 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.By
localDurableType()
-- those will persist between invocations and between recompilations with the same compiler. It saves manual definition ofdurableType()
method when defining complex events.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 definedurableType()
if you're not using theNEW_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
精彩评论