2

I have a QToolButton with an attached QMenu which includes a couple of QActions. One of those actions is the button's default action. The default action dynamically changes when clicking on the actions and this works great.

Now, these QActions get enabled and disabled by signals. When exactly the (current) default action get's disabled, the QToolButton gets disabled, too.

This results in an inaccessible QMenu which still contains enabled QMenu entries (QActions) that I want to be able to select.

So: Can I somehow still make the Menu available when the default action is getting a setEnabled(false)? Or are there some other Ideas?

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Lars
  • 81
  • 1
  • 8

3 Answers3

1

I did the following to exactly resolve the issue as described:

In my QToolButton class I override eventFilter as follows:

bool MultiToolButton::eventFilter( QObject* inObject, QEvent* inEvent )
{
  MultiToolButton* _multiToolButton = 
    dynamic_cast<MultiToolButton*>(inObject);
  QMouseEvent* _mouseEvent = dynamic_cast<QMouseEvent*>(inEvent); 

  if(_multiToolButton 
    && _mouseEvent && _mouseEvent->type() == QEvent::MouseButtonPress)
  {
    mMenu.setEnabled(true);
    showMenu();
    return true;
  }

  return QToolButton::eventFilter(inObject, inEvent);
}

and add the following line to the contructor:

installEventFilter(this);

Thank you for your answer nonetheless. However, I didn't check it.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Lars
  • 81
  • 1
  • 8
  • I used a variant of this solution (thanks!). Is there a way to also paint the menu arrow correctly (enabled instead of disabled)? – Compholio Dec 21 '16 at 20:46
0

Naively what you can do is to write a small function that you call whenever you disable a QAction to see if it is the current default action with somethinglike this:

void MyDialog::on_button_clicked()
{
  action2->setEnabled( false );
  checkForDefault(action2);
}

void MyDialog::checkForDefault(QAction *action)
{
  if ( tButton->defaultAction() == action ) {
    QList<QAction*> list = tButton->menu()->actions();
    int index = list.indexOf(action);
    QAction *newDefault = list.at( ( index+1 ) % list.count() );
    tButton->setDefaultAction(newDefault);
    tButton->setEnabled(true);
  }
}

This will check if the action that was changed is the current default action of the button and if so will select the next QAction within the QMenu as the new default (or the first action if the disabled action is the last in the list).

A different way would probably be to have your own class inheriting from QToolButton and to overload its actionEvent ( QActionEvent * event ) method to perform what you need.

Is this of any help?

Erik
  • 2,137
  • 3
  • 25
  • 42
0

The problem of the arrow being disabled can be solved by the following stylesheet, which replaces the standard arrow with an image located in url path_to_arrow. This image does not changed when the button is disabled :

QToolButton::menu-indicator,::menu-button 
{

}

QToolButton::menu-arrow
{

    image: url("path_to_arrow");

}
S.I.
  • 3,250
  • 12
  • 48
  • 77