[Qt-interest] QgraphicsScene: best way to manage events
Oliver.Knoll at comit.ch
Oliver.Knoll at comit.ch
Thu Nov 25 13:57:29 CET 2010
On 2010-11-25 Christian Christian Gagneraud wrote:
> ...
> I thought about this one, but it didn't looks like to me to be in the "QT spirit" hence
Oh and I think having mouseMoveEvent() etc. exposed on the "Tool Interface" is pretty much "in the Qt spirit". After all that's how you implement your concrete subclasses of QWidget as well: the QWidget provides mouseMoveEvent() methods which you can overwrite or not, and the Qt event queue then starts traversing over the "focus widget" and its children, until some child or the focus widget itself decides to "consume" (accept) the event. So the Qt event queue does exactly the same basically as the approach with my ToolManager which provides the "focus tool" (or active tool) and the graphicsview would then simply forward the events to that "focus tool", by calling the provided mouseMoveEvent() etc. methods - just like the event queue.
However the QGraphicsView/Scene might already provide other means of adding "event hooks" into its mouse/keyboard handling.
The "event filters" you mentioned on the other hand are mostly of interest when you:
- want to catch platform specific events aka "native events" (e.g. generated from some 3d mouse device)
See http://doc.trolltech.com/4.7/qcoreapplication.html#setEventFilter
Note that here we are really talking about platform specific events such as MSG on Windows or XEvent on X11
- want to send or post (1) a "custom event" from one QObject to some other QObject
http://doc.trolltech.com/4.7/qcoreapplication.html#sendEvent
http://doc.trolltech.com/4.7/qcoreapplication.html#postEvent
note that we are talking about "Qt events" (QEvent)
(1) There is a subtle but important difference between "send" and "post":
"send" sends the event /directly/ - or immeditatelly - to the receiver, that is a direct method call is done in the end. Or more importantly: the receiver event handler is executed in the /same/ thread as the caller is living in.
"post" on the other hand is /thread safe/ and it merely queues the event into the Qt event queue. The event will then - eventually, at some later point - be delivered to the receiver. The important part here is that the receiver then executes its event handler in the same thread as the Qt event queue, e.g. it can then safely update widgets, paint on QPixmaps etc.. In Qt 3 times this was a way to let a "worker thread" tell the "GUI thread" (aka "main thread") that it had calculated something and "now is the time to update the widgets accordingly" (because everyone knows that painting is only allowed in the "GUI thread"!).
Nowadays - with Qt 4 - this is done with "asynchronous" aka "queued connections" (http://doc.qt.nokia.com/4.7/qt.html#ConnectionType-enum), so now a thread can emit a queued signal which is then received by the sender in the GUI thread (or more precisely: "in the receiver thread", in case the receiver is running its own event queue - in practice this will mostly be the main Qt event queue).
Also note that there is a http://doc.trolltech.com/4.7/qcoreapplication.html#notify flavour, but to be honest I don't know the subtle difference between "send" and "notify": I guess the difference is how "QObject hierarchies" are dealt with (traversing the children).
Summary: I guess event filters and sending custom events is really only useful in "rare cases" when you want to either deal with system-specific messages, or you want to invent our own events which are not covered by QEvent and children, or you need to "post" events across thread boundaries (however the new way to do this is "queued signals", which does exactly that for you).
However you could also figure out the "active tool" and "send" (forward) the mouse events you have received with
http://doc.trolltech.com/4.7/qcoreapplication.html#sendEvent
The advantage of this approach - now that I think about it - would be that you don't need to expose mouseMoveEvent() etc. methods in the tool interface, as long as the tool is QObject based. And you could send all sorts of events, basically every mouse/keyboard/drag'n'drop/... event you don't handle in the QGraphicsView! Just send it to the "active tool" and let the tool decide what it does (or does not) with the QEvent :)
I hope this does not confuse you too much, and gives you some rough ideas about event handling in Qt. Off course it is always worthwhile to see what the docs say all about it: http://doc.trolltech.com/4.7/eventsandfilters.html :)
Cheers, Oliver
--
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22
More information about the Qt-interest-old
mailing list