Qt: определение настраиваемого типа события
Я создал пользовательское событие в моем приложении Qt, выполнив подкласс QEvent.
class MyEvent : public QEvent
{
public:
MyEvent() : QEvent((QEvent::Type)2000)) {}
~MyEvent(){}
}
Чтобы проверить это событие, я использую следующий код в методе event():
if (event->type() == (QEvent::Type)2000)
{
...
}
Я хотел бы иметь возможность определять настраиваемое событие типа где-то в моем приложении, так что мне не нужно указывать фактическое целое число в методах событий. Поэтому в моих методах event() я хотел бы сделать что-то вроде
if (event->type() == MyEventType)
{
...
}
Любые мысли о том, как и где в коде я могу это сделать?
Ответы
Ответ 1
Если тип события идентифицирует ваш конкретный класс, я бы добавил его:
class MyEvent : public QEvent {
public:
static const QEvent::Type myType = static_cast<QEvent::Type>(2000);
// ...
};
// usage:
if(evt->type() == MyEvent::myType) {
// ...
}
Ответ 2
Для удобства вы можете использовать статическую функцию QEvent:: registerEventType() для регистрации и резервирования настраиваемого типа событий для вашего приложения. Это позволит избежать случайного повторного использования настраиваемого типа событий, который уже используется в другом месте вашего приложения.
Пример:
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
Идиоматическим способом решения таких проблем является создание класса оболочки шаблона, использование CRTP. Для каждого настраиваемого типа событий такой шаблон представляет новый тип, поэтому для каждого типа существует отдельный член staticType()
, возвращающий свой уникальный зарегистрированный тип.
Ниже я даю три способа идентификации типов:
-
В staticType()
- это полезно только при вызове приложения, и это тип, который будет использоваться с QEvent
. Значения не гарантируются одинаковыми между вызовами приложения. Они не принадлежат к длительному хранению, как в журнале.
-
В localDurableType()
- они будут сохраняться между вызовами и между перекомпиляциями с тем же компилятором. Он сохраняет ручное определение метода durableType()
при определении сложных событий.
-
В 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