PDA

View Full Version : QMenu: remain visible while mouseOver



vonCZ
24th October 2007, 10:33
I have a standard pushButton with a Menu and a few Actions. The default behavior: when an action is clicked, the menu closes. Is there a way to change the behavior such that the Menu remains open/visible while so long as the mouse is over it? (i.e. doesn't close when an action is clicked)

high_flyer
24th October 2007, 11:18
one way you could try is to catch the aboutToHide () signal, and in the slot call show().

vonCZ
24th October 2007, 12:20
thanks hf, that's a start... that never ends. ;)



connect(myMenu, SIGNAL(aboutToHide()), this SLOT(menuSL()));

void Window::menuSL()
{
show();

// is it possible to do something here like:
// if(myMenu->QWidget::leaveEvent) hide();
// else show();

}


Above won't allow the menu to close, since show() is called before every attempt. Obviously, I need to test whether the mouse is over the menu or not, like in the comments.

How to do this? I already have an eventFilter that checks if the mouse is over this widget for other reasons. Perhaps I should simply amend this eventFilter to check for buttonPresses: if pressed over my menu, do show(), and if menu leave, then hide(). Seems like overkill, though.

high_flyer
24th October 2007, 12:54
Obviously, I need to test whether the mouse is over the menu or not, like in the comments.
I thought it was abovious too.
You didn't expect us to deliver you every little detail did you? ;)

If I understand correctly, you want to have the menu stay visible as long as your cursor is above it, even if you made your selection - is that correct?
So testing to see if the mouse button is clicked wont bring much.

But you could try the following:


void Window::menuSL()
{
if(myMenu->isUnderMouse())
myMenu->show();
}


and in your event filter, look for QEvent::Leave to hide the menu once the mouse has left it.

vonCZ
24th October 2007, 13:53
You didn't expect us to deliver you every little detail did you?

...yeah, eventually.:p

Thanks a mill: underMouse() did tha' trick.

vonCZ
24th October 2007, 18:15
...i spoke too soon: more difficulties. The pushButton isn't staying checked while the menu is up.

I've setCheckable(false) on my pushButton. Normal behavior: the button is pressed/checked while the menu is up, then as soon as a menu selection is made, the menu disappears and the button goes back to checked(false).

I've modified the menu to stay up while moused Over per hf's advice, above.

I would like the button to stay checked while the menu is up, then unchecked when it disappears (basically what you'd expect). I'm getting the following behavior, however: when I select an Action on the menu, the button changes to checked(false)... even though the menu is still up. If I make more selections, the button changes to checked(true) and stays that way. I've done this:



void Window::menuSL()
{
if(myMenu->isUnderMouse())
{
myButton->setChecked(true);
myMenu->show();
}
}

//I also added a new SLOT and connected it to the Actions:

void Window::actionSL()
{
qDebug("actionSL"); // this works
myButton->setChecked(true);
}

Neither of these have any effect: the button changes to checked(false) as soon as an action is selected (even though the menu is still up). Advice?

high_flyer
24th October 2007, 20:03
The pushButton isn't staying checked while the menu is up.
I was not aware you were popping a menu as a reaction to a toggle button.

the button changes to checked(false)... even though the menu is still up.
That is because the QAction object is still doing its work, and the button is connected to it.
They both don't know you are "cheating" with the menu. (making it behave in a way not consistent with what the QAction scheme is design to do)

In your case I would reconsider using QAction, and just make your own signal slot connections.
QAction and other such mini frameworks are designed to make life easier for common coding tasks, but if you want something different, then you might be better of doing things your own way.

Any how, how about the following:



//somewhere:
connect(myButton,SIGNAL(toggled(bool)),this,SLOT(c heckMenuState(bool)));

void Window::checkMenuState(bool checked)
{
if(myMenu->isUnderMouse() && !checked)
{
myButton->setChecked(true);
{
}


It could be that you will have also have to take care of the un-checking your self when the menu closes.

vonCZ
25th October 2007, 07:54
In your case I would reconsider using QAction, and just make your own signal slot connections.

Yeah, I thought I might have to drop QAction; if I do so, don't I also have to drop QMenu?


A menu consists of a list of action items... There are three kinds of action items: separators, actions that show a submenu, and actions that perform an action.

If so: what to use instead? A drop-down menu that closes when the mouse has left this menu would seem like a pretty basic feature. Surely there's a relatively simple way to do it...

I tried your checkMenuState idea. Doesn't work either.

wysota
25th October 2007, 08:33
I'd use a custom widget with QToolButtons (so that you can still use actions) in a vertical layout and monitor for enter and leave events. And probably make that widget a popup as well by using appropriate window flags.

vonCZ
25th October 2007, 10:59
I'd use a custom widget with QToolButtons (so that you can still use actions) in a vertical layout and monitor for enter and leave events. And probably make that widget a popup as well by using appropriate window flags.

I don't follow. You mean a custom widget (like a QFrame?) that has the 2 actions in a vertical layout... which pops-up when the QToolButton is pressed?

wysota
25th October 2007, 16:54
Yes, something like that. Just not a QFrame but QWidget. There is no reason for using a frame here.