9

I need to create several custom event classes for a Qt application.

Right now, it looks like I will need to implement the following event type registration code for each event class:

class MyEvent : public QEvent
{
public:
    MyEvent() : QEvent(registeredType())
    {
    }

    static QEvent::Type eventType;

private:
    static QEvent::Type registeredType();
}

QEvent::Type MyEvent::eventType = QEvent::None;

QEvent::Type MyEvent::registeredType()
{
    if (eventType == QEvent::None)
    {
        int generatedType = QEvent::registerEventType();
        eventType = static_cast<QEvent::Type>(generatedType);
    }
    return eventType;
}

Any suggestions on how I can simplify this, or at least hide it with a macro?

Tony the Pony
  • 40,327
  • 71
  • 187
  • 281
  • 1
    You can also have a look at [this stackoverflow post](http://stackoverflow.com/a/8232397/5253471). It worked well for me. – Francois Dec 16 '15 at 18:19
  • 1
    @Francois Yes, the answer you have linked to provides a more elegant solution than this plus the fact that in general event types are defined as constants in order to prevent overriding an event out of nowhere. – rbaleksandar Feb 04 '17 at 15:44

1 Answers1

9

That's what templates are for. They can be used with constant integral parameters, which need to be known at compile time too:

enum EventNames { UpdateEvent,... }

template<EventNames E>
class MyEvent : public QEvent
{
public:
    MyEvent() : QEvent(registeredType())
    {
    }

    static QEvent::Type eventType;

private:
    static QEvent::Type registeredType();
}

The common code lokes like this:

template<EventNames E>
QEvent::Type MyEvent<E>::registeredType()
{
    if (eventType == QEvent::None)
    {
        int generatedType = QEvent::registerEventType();
        eventType = static_cast<QEvent::Type>(generatedType);
    }
    return eventType;
}

Static initialization (beware!) looks like this:

QEvent::Type MyEvent<UpdateEvent>::eventType = QEvent::None;

The code specific for each event type can be implemented as template specialization then.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • Great! If I create additional event classes, does that mean I will need to change the `enum`? – Tony the Pony Jun 03 '11 at 08:39
  • Yes. You will also need a initialize each template-static, but if you create more than one event object from a given type, they will share the static as usual – Gunther Piez Jun 03 '11 at 08:48
  • 3
    You can also just initialize the template-static with a template: `template QEvent::Type MyEvent::eventType = QEvent::None;`, then you don't need to update the initialization for every event type. This is about the only place where you can use templates on non-class non-function types. – Xeo Jun 03 '11 at 09:10