Идиоматический способ решения таких проблем - создать класс-оболочку шаблона, используя CRTP . Для каждого пользовательского типа события такой шаблон представляет новый тип, поэтому для каждого типа существует отдельный элемент staticType()
, возвращающий свой уникальный зарегистрированный тип.
Ниже я приведу три способа определения типов:
By staticType()
- это полезно только в вызове приложения и является типом, который будет использоваться с QEvent
. Значения не гарантированно остаются одинаковыми между вызовами приложения. Они не относятся к долговременному хранению, как в журнале.
By localDurableType()
- они будут сохраняться между вызовами и перекомпиляциями с одним и тем же компилятором. Сохраняется ручное определение метода durableType()
при определении сложных событий.
By durableType()
- они действительно кроссплатформенные и будут одинаковыми, если вы не измените имена классов событий в своем коде. Вы должны вручную определить durableType()
, если вы не используете макрос NEW_QEVENT
.
И localDurableType()
, и durableType()
отличаются между Qt 4 и 5 из-за изменений в qHash
.
Вы можете использовать заголовок любым из двух способов:
#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