[Qt-interest] QgraphicsScene: best way to manage events

Christian Gagneraud cgagneraud at techworks.ie
Thu Nov 25 15:49:31 CET 2010


On 11/25/2010 12:57 PM, Oliver.Knoll at comit.ch wrote:
 > 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 :)

This is exactly what I was thinking about, with the first method, the 
handle events functions have to be public, with this method, they are 
protected, that what I meant by "the QT way".
This approach require a bit more work, but nothing crazy. I'm gonna 
give it a try, as anyway, the piece of code I'm working on is only for 
learning purpose.

So, for what I understood, I would have to implement the 
ToolInterface::event() function which will have in turn to call the 
corresponding virtual event handlers (ToolInterface::mouseMoveEvent(), 
...) depending on the event::type().

 > 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 :)

No you didn't confuse me at all, actually it was a real pleasure to 
read all your detailed explanations! ;)


Thanks,
Chris

 >
 > Cheers, Oliver -- Oliver Knoll Dipl. Informatik-Ing. ETH COMIT AG -
 > ++41 79 520 95 22
 >
 >
 >
 > _______________________________________________ Qt-interest mailing
 > list Qt-interest at trolltech.com
 > http://lists.trolltech.com/mailman/listinfo/qt-interest


-- 
Christian Gagneraud,
Electronics and software engineer

TechWorks Marine Ltd
4a, Park Lane
Dun Laoghaire, Co Dublin
Ireland

Tel: + 353 1 2365990
Fax: + 353 1 2365992
Web: www.techworks.ie





More information about the Qt-interest-old mailing list