2012-02-08 24 views
11

首先,我有一个QWidget的列表,我不知道直到运行时的长度。然后,我创建一个QListWidget,在那里显示它们,当有人点击它们时,我使用信号currentItemChanged(QListWidgetItem*, QListWidgetItem*)来捕捉它并获取点击项目的索引。如何将QA列表添加到QMenu并使用单个插槽处理它们?

现在我想在QMenu中做类似的事情。当QMenu及其动作被构建时,我会知道该列表,但是我无法对此进行硬编码。

如何创建动作,捕获它们的信号并将它们连接到相同的插槽,根据菜单列表中动作的位置(索引)做出不同的事情?由于其他应用程序使用它,必须有一些方法来解决这个问题。我试图看看映射,但我无法理解如何使用它。

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

回答

15

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

然后,您将能够通过slot参数的QAction::data()函数检索数据。

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

} 

其它方法:信号映射或使用sender(),在that article of Qt Quaterly进行说明。

+0

哦谢谢!我实际上通过使用操作.property并将“index”设置为“i”(使用for-loop)来以类似的方式解决它。我猜数据将是解决它的另一种方式:) – chikuba 2012-02-08 19:42:02

+0

我尝试使用相同的解决方案,但它不起作用。你可以看看http://stackoverflow.com/q/14151443/986760和帮助。谢谢? – fayyazkl 2013-01-04 05:51:41

3

一个更通用的(不是特定于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*))); 
} 

,并在插槽:

void MyClass::MySlot(QAction* triggeredAction) 
{ 
    // use either the action itself... or an offset 
    int value = triggeredAction->data().toInt() 
} 
相关问题