如何将QActions列表添加到QMenu并使用单个插槽处理它们?

chi*_*uba 12 c++ qt slot qmenu

首先,我有一个QWidgets 列表,我不知道运行时的长度.然后我创建了一个QListWidget我显示它们的位置,当有人点击它们时,我使用信号currentItemChanged(QListWidgetItem*, QListWidgetItem*)来捕获它并获得被点击项目的索引.

现在我想做一个类似的事情QMenu.当QMenu它及其动作构建时我会知道列表,但是我将无法对其进行硬编码.

如何根据菜单列表中的操作位置(索引)创建操作,捕获信号并将它们连接到同一个插槽,这些插槽会执行不同的操作?必须有一些方法来解决这个问题,因为其他应用程序使用它.我试着看一下映射,但我无法理解如何使用它.

我试图抓住sender插槽,但无法从中获取任何有用的信息.

ale*_*sdm 18

您可以在创建索引时将索引(或任何其他数据)与每个操作相关联QAction::setData,并将信号连接QMenu::triggered(QAction*)到您的插槽.

然后,您就可以通过QAction::data()slot参数的功能检索数据.

MyClass::MyClass() {
    // menu creation
    for(...) {
        QAction *action = ...;
        action->setData(10);
        ...
        menu->addAction(action);
    }
    // only one single signal connection
    connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(mySlot(QAction*)));
}

void MyClass::mySlot(QAction *action) {
   int value = action->data().toInt();

}
Run Code Online (Sandbox Code Playgroud)

其他方法:信号映射或使用sender(),在Qt Quaterly的文章中进行了解释.


Fox*_*Fox 5

解决此问题的更通用(不是特定于 QMenu)的方法是QActionGroup类。这允许您将特定菜单项隔离为相关组,或将不同的小部件分组在一起。

void MyClass::InitMenu(QMenu* menu)
{
    QActionGroup* actions1 = new QActionGroup(menu);
    actions1->setExclusive(false);
    actions1->addAction(menu->addAction(tr("Action1")))->setData(1);
    actions1->addAction(menu->addAction(tr("Action2")))->setData(2);
    actions1->addAction(menu->addAction(tr("Action3")))->setData(3);
    actions1->addAction(menu->addAction(tr("Action4")))->setData(4);
    actions1->addAction(menu->addAction(tr("Action5")))->setData(5);
    connect(actions1, SIGNAL(triggered(QAction*)), SLOT(MySlot(QAction*)));

    QActionGroup* actions2 = new QActionGroup(menu);
    actions2->addAction(menu->addAction(tr("Undo Action1")))->setData(1);
    actions2->addAction(menu->addAction(tr("Undo Action2")))->setData(2);
    //...
    connect(actions2, SIGNAL(triggered(QAction*)), SLOT(MyUndoSlot(QAction*)));
}
Run Code Online (Sandbox Code Playgroud)

并在插槽中:

void MyClass::MySlot(QAction* triggeredAction)
{
    // use either the action itself... or an offset
    int value = triggeredAction->data().toInt()
}
Run Code Online (Sandbox Code Playgroud)