Qt: Определение пользовательского типа события - PullRequest
16 голосов
/ 12 февраля 2010

Я создал пользовательское событие в своем приложении 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)
{
  ...
}

Есть мысли, как и где в коде я мог бы это сделать?

Ответы [ 3 ]

16 голосов
/ 12 февраля 2010

Если тип события идентифицирует ваш конкретный класс, я бы поставил его там:

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

// usage:
if(evt->type() == MyEvent::myType) {
    // ...
}
15 голосов
/ 24 ноября 2010

Для удобства вы можете использовать статическую функцию 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;
5 голосов
/ 01 октября 2013

Идиоматический способ решения таких проблем - создать класс-оболочку шаблона, используя CRTP . Для каждого пользовательского типа события такой шаблон представляет новый тип, поэтому для каждого типа существует отдельный элемент staticType(), возвращающий свой уникальный зарегистрированный тип.

Ниже я приведу три способа определения типов:

  1. By staticType() - это полезно только в вызове приложения и является типом, который будет использоваться с QEvent. Значения не гарантированно остаются одинаковыми между вызовами приложения. Они не относятся к долговременному хранению, как в журнале.

  2. By localDurableType() - они будут сохраняться между вызовами и перекомпиляциями с одним и тем же компилятором. Сохраняется ручное определение метода durableType() при определении сложных событий.

  3. 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...