PDA

View Full Version : Closing out a animated context menu from any active screen



bob2oneil
10th February 2011, 16:47
I have written an application in QtCreator using standard widgets and animation content where the GUI mimics very closely that of modern smartphones (i.e. kinectic scrolling lists, animated screen transitions, integrated editors, etc.). I have a sliding content menu similar to a modern smartphone based on the use of an external command button. I want to close out this menu whenever the user presses anywhere in the application area. Mouse clicks within the content menu are handled with a button selection. However, I need to also hide the content menu if the user presses the mouse anywhere in the application area. The application has a dozen or more screens which could be active at any time with the content menu. Some of these screens have additional nesting, such as context specific editors, with individual widgets. This is show in the sample attached screenshot.

So my question is, what is the most efficient way of capture all mouse presses in the client area outside of the content menu itself. My preliminary implementation is to have each screen provide a signal within it's MousePress event, so the parent application can close out the content menu. However, I would prefer not having to implement this for each and every screen/form if there is a more efficient centralized way of doing it (from say the parent screen which contains the fixed header and footer components of the GUI).

It there a better way of implementing this other than having to add a mousePressEvent() handler to each child screen (or perhaps having each screen/form derive from a common base class containing this feature?).

Is there some form of mouse capture that can be performed when the context menu is made visible that could capture all mouse presses within the application, and then perhaps release this mouse capture upon menu closure. I need to eat the mouse press event outside the bounds of the context menu.

Since mouse presses may be frequent, I would prefer not to have to signal for each one.

high_flyer
11th February 2011, 09:11
One way is to make the application serve as event filter for the widgets.
So at creation time each widget installs the application event filter.
Then you will need to be able to access the animated menu object (for its state, and to close it)(if nothing else works, a global), and in the event filter all you do is:
if menu is visible AND event is a pressMouseEvent - you close the menu.
You only need to subclass one class (QApplication) for the event filter, and add the installEventFilter() to each widget you are interested to be part of this behavior.

bob2oneil
14th February 2011, 21:08
Thanks high_flyer for your advice. I currentlly have custom event filters for many widgets, so I will have to see how this plays with an application level filter. Perhaps I can use the app level filter as the base class, and then specialize my custom event filters from it.

bob2oneil
21st February 2011, 21:11
It is possible to cascade event filters so that they to some extent act in series? I already have event filters in place for various widgets to implement kinetic scrolling, swipe navigation, etc.

high_flyer
22nd February 2011, 09:10
It is possible to cascade event filters so that they to some extent act in series?
Can you explain maybe with an example what do you mean?
You can however ignore events, which then will be propagated further.

bob2oneil
25th February 2011, 17:46
Well, I have event filters for child windows similar to the following code segment. The Scroller() class provides an event filter on mouse events. So, could I reap the benefit of an application level event filter that applied to
all windows, and yet have the behavior of a customized version (sort of a class derivation metaphor). I would also need windows that do not currently have event filters work with the application level event filter. I have noticed that
for application windows/widgets which provide processing for mouse depressions (either through an event filter or an override of mousePressEvent()), the parent will not receive a mouse depression event if the child has a handler. I can always emit the signal to the parent, but for deeply nested content, I do not what to have this level of signals and slots to simply close out a context menu.



// Set up scroller event filter
m_scroller = new Scroller();
ui->ProgramListWidget->viewport()->installEventFilter(m_scroller);