0

我有一种方法可以在菜单上自动添加可检查的操作,并且运行良好。我只是想知道如何自动取消选中所有这些操作。我知道这是可能的,ui->action_item->setChecked(false)但在这种情况下,我应该知道并在代码中写下每个动作名称,但这对我来说不可行。

伪代码:

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);
    }
}
4

2 回答 2

1

我实现了一个最简单的解决方案:

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

foreach (QMenu* menu, menus)
{
    foreach (QAction* action, menu->actions())
    {
        if(action->isCheckable()){
        action->setChecked(false);
        }
    }
}
于 2018-03-08T20:59:02.937 回答
1

您需要获取操作列表,然后取消选中每个操作。操作列表只是QAction菜单的子项列表 - 但前提是它们不属于操作组。那将是:

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

如果要查找特定操作组中的操作,则需要使用唯一名称命名操作组,以便稍后引用:

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);
}

如果您有多个组,它们可以共享相同的名称,然后您也可以迭代它们:

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);
}

如果您的编译器尚未实现std::as_const,请qAsConst改用。const-casting 是 Qt 容器的隐式共享设计的不幸效果。

在多个地方引用的对象名称应用作带有符号名称的字符串常量。这使得在编译时可以检测到拼写错误,而不是在运行时检测。

于 2018-03-08T20:01:35.087 回答