I have created a custom event in my Qt application by subclassing QEvent.
class MyEvent : public QEvent
{
public:
MyEvent() : QEvent((QEvent::Type)2000)) {}
~MyEvent(){}
}
In order to check for this event, I use the following code in an event() method:
if (event->type() == (QEvent::Type)2000)
{
...
}
I would like to be able to define the custom event's Type somewhere in my application so that I don't need to cast the actual integer in my event methods. So in my event() methods I'd like to be able to do something like
if (event->type() == MyEventType)
{
...
}
Any thoughts how and where in the code I might do this?
An event filter gets to process events before the target object does, allowing it to inspect and discard the events as required. An existing event filter can be removed using the QObject::removeEventFilter() function.
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Qt is an event-based system, and all GUI applications are event-driven. In an event-driven application, there is usually a main loop that listens for events and then triggers a callback function when one of those events is detected.
Qt's event loop starts the moment the underlying application's exec() function gets called. Once started, the loop repeatedly checks for something to happen in the system, such as user-input through keyboard/mouse.
If the event-type identifies your specific class, i'd put it there:
class MyEvent : public QEvent {
public:
static const QEvent::Type myType = static_cast<QEvent::Type>(2000);
// ...
};
// usage:
if(evt->type() == MyEvent::myType) {
// ...
}
For convenience, you can use the QEvent::registerEventType() static function to register and reserve a custom event type for your application. Doing so will allow you to avoid accidentally re-using a custom event type already in use elsewhere in your application.
Example:
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;
The idiomatic way of dealing with such problems is to create a template wrapper class, leveraging CRTP. For each custom event type, such template represents a new type, thus a separate staticType()
member exists for each type, returning its unique registered type.
Below I give three ways of identifying types:
By staticType()
-- this is only useful within an invocation of the application, and is the type to be used with QEvent
. The values are not guaranteed to stay the same between invocations of an application. They do not belong in durable storage, like in a log.
By localDurableType()
-- those will persist between invocations and between recompilations with the same compiler. It saves manual definition of durableType()
method when defining complex events.
By durableType()
-- those are truly cross platform and will be the same unless you change the event class names within your code. You have to manually define durableType()
if you're not using the NEW_QEVENT
macro.
Both localDurableType()
and durableType()
differ betwen Qt 4 and 5 due to changes to qHash
.
You use the header in either of two ways:
#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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With