PDA

View Full Version : how to popup and close a QMenu



Placido Currò
14th May 2007, 09:58
Hi everybody,

if you have a QMenuBar and you want a QMenu to popup without worrying about its position, you can write this code, assuming mb as a QMenuBar:


mb->setActiveAction(mb->actions()[0]);

mb->actions()[0]->menu()->setActiveAction(mb->actions()[0]->menu()->actions()[0]);

the first statemet makes the QMenu popup and the second one makes the first QAction be selected.

But if you want to close the opened QMenu, what would you do ?


mb->actions()[0]->menu()->setActiveAction(0); works properly because it removes the selection on the first QAction of the QMenu

but


mb->setActiveAction(0); doesn't work because the QMenu remains opened.

What would you do to make it disappear ?

Thanks
Placido.

wysota
14th May 2007, 10:02
Call close() on the menu?

Placido Currò
14th May 2007, 10:04
it doesn't work !

I would like to supply other informations.

My QMenuBar is not docked on the top of the window (is not the menuBar() of the QMainWindow), but I build it into a position of the QMainWindow and after using it I have to destroy it. This is to describe you the situation.

If you execute the clear() or the hide() or the close() of the QMenuBar, you make it close, but the active menu doesn't close and it keeps the focus. If you execute the close of the QMenu it doesn't close.

wysota
14th May 2007, 10:07
Ok, anyway why are you doing such a strange thing as opening and closing the menu manually? It was not designer for this...

Placido Currò
14th May 2007, 10:13
If I could, I would not popup the QMenu at run-time. The problem is how to close it at run-time. The only working solution, as I know, is deleting the QMenu. But it creates problems with the remaining code.

Another consideration.

The popupped qmenu raises on the windows of the application you are viewing at that time. I don't know how to open it and not prevent it from raising at this way.


Coming soon, "don't popup that QMenu !"

wysota
14th May 2007, 10:18
But what do you need that functionality for? If you want a menu to be invactive, just disable it.

Placido Currò
14th May 2007, 10:22
I want to make it not visible, this is what I want. They want to reduce the number of the clicks you have to do with the mouse.

well, there would be a solution, but it doesnt' work perfectly. I can reduce the dimension of the QMenu,
resize(0,0) but the QMenu keeps the focus and it would be necessary to press ESCAPE to move the focus to elsewhere.

wysota
14th May 2007, 10:40
You mean you want to make collapsible menus? Try making the action responsible for the menu invisible (setVisible(false)).

Placido Currò
14th May 2007, 11:01
Thanks for your help.

I tried it but what I get is a void little rect at the same point where there was the qmenu. And then, I need to click on it to make this little rect to disappear.

wysota
14th May 2007, 11:15
Maybe you just need to update() the menu bar or the parent menu?

Placido Currò
14th May 2007, 11:35
:crying:

It doesn't work. It doesn't update. The rect remains, as if you build a QMenuBar with QMenus and no actions.

wysota
14th May 2007, 12:07
Seems to work quite fine for me...

Placido Currò
14th May 2007, 12:55
try these statements in a on_click() of QPushButton

mb->setActiveAction(mb->actions()[0]);

mb->actions()[0]->menu()->setActiveAction(mb->actions()[0]->menu()->actions()[0]);

then try to hide the first menu that has just appeared. I can close the qmenubar but the qmenu is open.

I do this inside a routine because if you click outside the menu, the qmenu closes regularly because another event has just fired on another object.

Sorry, if I insist.

wysota
14th May 2007, 13:35
But why do you setActiveAction at all? Could you explain what are you trying to achieve? QMenu closes because it is a popup window, not through any kind of magic. In your situation it doesn't close, because it is modal and you don't do anything to break the event loop.

Placido Currò
14th May 2007, 14:12
I need the setActiveAction because it opens the qmenu I need to show. I don't use the popup() or the exec() because the former opens the menu but not within the qmenubar and then if I click the right or left arrow the QMenuBar doesn't open the near menus and the latter suspends the event loop.

This is why I used this statement. My application must show a menu opened but close that menu if it receives a command to close the qmenubar, even before the human operator can do it. Imagine these events:

My application is a simple client whoose task is to draw and build the gui.

1) my application receives commands to build a qmenubar and show a qmenu
2) the operator chooses the menu
3) the operator does something...
4) the application receives a command to build a qmenubar and show a qmenu

my application takes a buffer of the events during the server-time and when it's ready to build the qmenubar it can receive the input to close the qmenubar before it has been displayed. In this case the application receives the command to close the qmenubar and obviously his opened children. This is what I can't do, closing the qmenus, if any is open.

wysota
14th May 2007, 16:41
Maybe you should operate on event level then? It might be a general way to handle many things, not only the menu.... I'm sure if you posted proper events to the menu, you'd get the effect you desire.