0

I have a method to automatically add checkable actions on a menu and it's working perfectly. I just like to know how to unchecked all these actions automatically. I know that it's possible with ui->action_item->setChecked(false) but in this case I should know and write each action name in the code however it's not viable for me.

Pseudo-code:

void MainWindow::AddNewActions() {
    QActionGroup *my_action_group = new QActionGroup(this);
    my_action_group->setExclusive(true);

    foreach (..) {
        QAction *my_new_action = new QAction(description, my_action_group);
        my_new_action->setCheckable(true);
        my_new_action->setData(action_name);

        ui_->my_menu->addAction(my_new_action);
    }
}
Jeff Pal
  • 1,519
  • 1
  • 17
  • 28

2 Answers2

1

You need to get a list of actions, and then uncheck each of them. The list of actions is simply the list of QAction children of the menu - but that's if they don't belong to an action group. That would be, then:

void Class::method2() {
  auto actions = std::as_const(ui_->my_menu->findChildren<QAction*>());
  for (auto *action : actions)
    action->setChecked(false);
}

If you want to find actions in a particular action group, you need to name the action group with a unique name, to refer to it later:

static const QString k_my_action_group{QLatin1String("my_action_group")};

void Class::method1() {
  auto *my_action_group = new QActionGroup{this};
  my_action_group->setObjectName(k_my_action_group);
  ...
}

void Class::method2() {
  if (auto *group = findChild<QActionGroup*>(k_my_action_group))
    if (auto *action = group->checkedAction())
      action->setChecked(false);
}

If you have multiple groups, they can share the same name, and then you'd iterate them too:

void Class::method2() { // if somehow more than one action can be checked
  auto groups = std::as_const(findChildren<QActionGroup*>(k_my_action_group));
  for (auto *group : groups)
    if (auto *action = group->checkedAction())
      action->setChecked(false);
}

If your compiler doesn't implement std::as_const yet, use qAsConst instead. The const-casting is the unfortunate effect of the implicit shared design of Qt containers.

Object names referred to in multiple places should be used as string constants with symbolic names. This makes typos detectable at compile time, vs. at runtime.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
1

I implemented a simplest solution:

    QList<QMenu*> menus;
menus = ui->menuBar->findChildren<QMenu*>();

foreach (QMenu* menu, menus)
{
    foreach (QAction* action, menu->actions())
    {
        if(action->isCheckable()){
        action->setChecked(false);
        }
    }
}
Jeff Pal
  • 1,519
  • 1
  • 17
  • 28