Search code examples
c++qtmacrosqevent

Is there a cleaner way to register Qt custom events?


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?


Solution

  • 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.