2012-02-08 9 views
11

Per prima cosa, ho un elenco di QWidget s che non conoscerò la lunghezza fino al runtime. Creo quindi uno QListWidget dove li mostro e quando qualcuno li fa clic, uso il segnale currentItemChanged(QListWidgetItem*, QListWidgetItem*) per catturarlo e ottenere l'indice dell'elemento selezionato.Come aggiungere un elenco di QActions a un QMenu e gestirli con un singolo slot?

Ora voglio fare una cosa simile nel QMenu. Conoscerò l'elenco quando il QMenu e le sue azioni verranno compilati, ma non sarà possibile codificarlo.

Come posso creare azioni, catturare i loro segnali e collegarli allo stesso slot che fa cose diverse a seconda della posizione dell'azione (indice) nell'elenco dei menu? Ci deve essere un modo per risolvere questo problema poiché altre applicazioni lo usano. Ho provato a guardare la mappatura ma non riuscivo a capire come usarlo per questo.

Ho provato ad afferrare lo sender nello slot ma non sono riuscito a ottenere alcuna informazione utile da esso.

risposta

15

È possibile associare un indice (o qualsiasi altro dato) a ciascuna azione quando vengono creati con QAction::setData e collegare il segnale QMenu::triggered(QAction*) allo slot.

Sarai quindi in grado di recuperare i dati tramite la funzione QAction::data() del tuo parametro di 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(); 

} 

Altri metodi: la mappatura del segnale o l'uso di sender(), sono spiegate in that article of Qt Quaterly.

+0

Oh grazie! L'ho risolto in un modo simile usando le azioni .property e impostando "index" su "i" (usando un ciclo for). Immagino che i dati siano un altro modo per risolverlo :) – chikuba

+0

Ho provato a utilizzare la stessa soluzione, ma non funziona. Potete per favore dare un'occhiata a http://stackoverflow.com/q/14151443/986760 e aiutare. Grazie? – fayyazkl

3

Un modo più generico (non specifico per QMenu) per avvicinarsi a questo è la classe QActionGroup. Ciò consente di isolare voci di menu specifiche come gruppo correlato o raggruppare insieme diversi widget.

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

e nello slot:

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