Events [Solved]
-
I am new to Qt events. For a while, I have been making simple applications using signals and slots, but now I am wondering how events work.
What I think is right so far is that events are all from the QEvent data type (or subclass), and when you reimplement the event (lets use QKeyEvent as an example), and the event is put into the queue, the next frame will execute the function. Is this correct? What is the full process of how an event is called and what happens?
I am trying to create my own custom events. However, I was reading about the QCustomEvent class and it is outdated. How would I go about doing this?
-
everything described in documents http://doc.qt.digia.com/4.8-snapshot/eventsandfilters.html
-
Okay, let me check that out.
I have some questions:
When does an event "occur"? I'm especially wondering about this for custom events, because I'm not sure if it always occurs when a mouse is clicked. For custom events, is it when you send the event into the queue and then waits to be processed by the event() function?
What happens with custom events? Do they have a QEvent::Type? Is this the number between 1000 and 6563?
What is the recipient of an event? It seems to be in functions like postEvent(), sendEvent(), etc.
The document says that the event() function does not call the function that I would reimplement. Qt has it so that a virtual function is called. How would they know which virtual function should be called, especially for custom events? Do you have to put it in the event() function, or if you want a filter the eventFilter() function?
When should you use a custom event instead of a signal?
-
Events can have their source inside or outside of the application. A mouse or keyboard event would normally come from the system, so from outside of the application. QApplication has the responsibility to communicate with the system on your behalf for this. So, when the application is signalled by the OS that an event has happened, QApplication (and the machinery behind it) will make sure the event is translated to a QEvent, and added to the queue and finally delivered to the right object.
Custom events should also have an Event::Type, but indeed only between values QEvent::User and QEvent::MaxUser
The recipient of an event is a QObject. For a mouse move, it would be the widget the mouse is over, or the widget that is currently tracking the mouse.
For custom events, you can do either of the approaches you suggest. Reimplementing event() will work, but don't forget to also call the base implementation to make sure other events besides your custom one will still be properly processed. I would suggest you use the same pattern as used by Qt itself: from your reimplemented event() function (which is public), you call a (protected) virtual myCustomEvent(CustomEvent* e) if the event you got is of your custom event type. In there, you do the actual processing of the event.
Events and signals are very different patterns. An event is send to a specific receiver. So, it is a single cast, and you know to who. A signal can be connected to by any other object. The emitter has no and needs no knowledge of the receiver.
-
Thanks for the response.
When you suggest reimplementing the event() function, you also note that I should call the base implementation so other stuff in the loop are processed as well. How would I do this?
I also "created a thread":http://qt-project.org/forums/viewthread/20662/#99300 focused on QEvent::registerEventType(), because that also seems to be a valid way. Is that way better, or do you still believe that reimplementing event() is better.
Once again, thanks.
-
[quote author="Flurite" date="1348788661"]Thanks for the response.
When you suggest reimplementing the event() function, you also note that I should call the base implementation so other stuff in the loop are processed as well. How would I do this?[/quote]
Say, you are creating your new eventhandler in a class derived from QObject. Your implemenation of the eventhandler would look something like:
@bool MyClass::event(QEvent* e)
{
if (e && e->type() == MyCustomEventType) {
MyCustomEvent* ce = dynamic_cast<MyCustomEventType*>(e);
return handleCustomEvent(e);
}
// very important: still handle all the other Qt events!
return QObject::event(e);
}
@The last line is the key for handling everything that you are not. Sometimes you want that to happen last, sometimes first, and sometimes somewhere in the middle, but you almost always want it to happen. Make it a habbit for every virtual you reimplement to call the base implementation by default, especially for event handling.
[quote]
I also "created a thread":http://qt-project.org/forums/viewthread/20662/#99300 focused on QEvent::registerEventType(), because that also seems to be a valid way. Is that way better, or do you still believe that reimplementing event() is better.Once again, thanks.[/quote]
That is a different issue, and orthogonal to this one. The registerEvenType() is only used to make sure you don't accidentally use the same ID for two different event types. That can easily happen if you use plugins, for instance. If each of these independent plugins want to register custom events, but they know nothing of each other, then you need some kind of registration mechanism to make sure eventID's don't start clashing.
I did notice your question, but I did not answer it because I was as suprised as you were that the QEvent::type() method actually returns Type. I would have expected an int there.
-
Are you allowed to call QObject::event() like that? It's not a static function, and I does this function call functions in the event loop?
-
This is basic C++. The call to QObject::event() is not a call to a static function, but a call to a function in a baseclass that you explicitly name. All this call does, is make sure that if your implementation of event doesn't handle the call, you give the base class the opportunity to do it for you.
I don't quite understand your second question.
-
I completely forgot about that you can add functionality to child classes by calling parent functions.
Thanks.