[Qt-interest] event/signal for when popup QMenu is hidden without selecting an action?

Ross Bencina rossb-lists at audiomulch.com
Wed Jul 14 13:09:29 CEST 2010


Hi All

I am trying to work out how to get an notification that a menu shown with 
QMenu::popup() has been closed when no item is selected (ie if someone 
clicks outside the popup menu). I have code that used to work but it's 
broken on Mac now. Here's how I've been doing it:

    // show the menu
    menuBeingShown_ = true;
    menu_->popup( pt, action );

What I was doing is using the following signal handler on the 
QMenu::aboutToHide() signal to detect when the menu was hidden without 
selecting an item by checking currentAction() on the menu.

void X::menuAboutToHide() // slot connected to QMenu::aboutToHide()
{
    if( menuBeingShown_ && menu_->currentAction() == 0 ){ // the menu is 
being hidden by something other than clicking on an action
        // cancel the operation, no action was selected
        menuBeingShown = false;
    }
}

void X::menuTriggered( QAction *a ) // slot connected to QMenu::triggered()
{
    if( menuBeingShown_ ){
        // respond to the action
    }
}

As of 4.6.3, this works on Windows, but is broken on Mac/Carbon. I believe 
it did work on Mac/Carbon 4.4.3 but I'm not 100% sure about that. I am not 
certain this is a bug or if I'm doing this the wrong way.

The problem is that on OSX, menu_->currentAction() is always zero when 
menuAboutToHide() is triggered. What's more, menuAboutToHide() is delivered 
before menuTriggered() so I don't have the option of waiting to see if 
menuTriggered() was called before responding to menuAboutToHide(). I have 
tried a number of strategies to defer the invocation of menuAboutToHide() so 
that I get menuTriggered() first (Deferred connection, singleShot 0ms timer 
to a second slot, similar things with event filters on QEvent HideEvent) but 
none of these work -- because QMenu pumps the event queue when hiding, and 
flushes all my deferred events -- any other ideas how I might defer the 
invocation of menuAboutToHide past the invocation of menuTriggered?


The spec for menu_->currentAction()  is vague, so I'm not even sure it's 
supposed to be valid in QMenu::aboutToHide(), is it? It is valid on Windows 
and my code works great.

What is really needed is another signal hiddenNoActionTriggered()

I can file a bug but I'm shipping my final beta next week and this is a 
showstopper... any ideas?

Many Thanks!

Ross.




More information about the Qt-interest-old mailing list