2016-06-23 2 views
1

Je travaille actuellement sur un jeu avec un de mes amis, et maintenant nous sommes coincés. Nous devons passer deux arguments à un slot. Je veux utiliser un slot pour deux boutons, et l'un des boutons sera utilisé pour l'ajout, et l'autre pour la soustraction. Ce sera l'un des arguments, soit 0 (pour la soustraction) ou 1 (pour l'ajout). L'autre argument sera une sorte d'identifiant, car j'aurai plusieurs ensembles de ces deux boutons. Je l'ai utilisé plusieurs autres emplacements dans mon code, et sur ces emplacements que je me sers QSignalMapper comme ceci:Passer plusieurs arguments à l'emplacement

Button * button = new Button(argument1, argument2, argument3); 

int num = 1; 

QSignalMapper * signalMapper = new QSignalMapper(this); 

connect(button, SIGNAL(clicked()), signalMapper, SLOT(map))); 
signalMapper->setMapping(button, num); 
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int))); 

scene->addItem(button); 

Est-il possible que je peux passer deux arguments à une fente?

+0

Je ne suis pas vraiment familier avec qt, mais qu'en est-une paire '' ? – user463035818

+0

Comment utiliser la paire '? – Dromnes

+0

sont des fentes et des signaux vraiment restreints à un seul paramètre? Cependant, voir ici: http://en.cppreference.com/w/cpp/utility/pair – user463035818

Répondre

2

QSignalMapper a un seul paramètre seulement. Mais vous pouvez utiliser l'une des façons suivantes pour diviser les boutons dans les différents ensembles:

  • commencer chaque ID de jeu à partir d'un nombre connu, à savoir premier jeu commence à partir de 100, la deuxième série de 200 et ainsi de suite, et vous peut facilement détecter l'ensemble en divisant un nombre par 100: 102 représente le premier ensemble et le bouton ID = 2;
  • utilisez le mappage avec QString où vous pouvez utiliser un jeton pour diviser un numéro d'ensemble à partir d'un numéro de bouton, à savoir 1;2 (le premier ensemble, ID de bouton = 2) à l'aide de QString::split().

Exemple de la fente:

void mySLot (const QString& id) 
{ 
    QStringList tokens = id.split (";"); 

    if (tokens.count() == 2) { 
     int setId = tokens.at(0).toInt(); 
     int buttonId = tokens.at(1).toInt(); 

     /* Your code goes here */ 
    } 
} 
+0

Pouvez-vous me montrer un exemple plus détaillé de la dernière façon, la méthode QString :: split()? – Dromnes

3

Utilisez la fonction sender() à la place:

void mySlot() 
{ 
    if (sender() == addButton) 
     ... 
    else 
     ... 
} 

Dans votre cas, vous pouvez supprimer l'argument int de mySlot et procédez comme suit:

connect(addButton, SIGNAL(clicked()), someObject, SLOT(mySlot())); 
connect(subButton, SIGNAL(clicked()), someObject, SLOT(mySlot())); 

Utilisez ensuite la fonction sender pour déterminer la source.

Pour répondre directement à votre question, oui, vous pouvez définir une fente qui accepte jusqu'à 8 arguments (pré C++ 11) ou un nombre quelconque (11 C++ ou ultérieure). Le problème est qu'ils doivent être connectés à un signal avec autant ou plus de paramètres.

Par exemple, si vous avez un signal avec la signature notify(int, bool, QString) vous pouvez le connecter à une fente avec l'une des signatures suivantes:

  • someSlot(int)
  • someSlot(int, bool)
  • someSlot(int, bool, QString)
+0

Hrmpf. Vous me battez dessus :) – JvO

+0

@Jon Harper Quand j'utilise la fonction 'sender()', l'expéditeur est 'QSignalMapper (0x324e028)', donc je ne comprends pas vraiment comment je devrais l'utiliser. – Dromnes

+0

Élimine 'QSignalMapper' entièrement et connecte le signal' clicked' du bouton à 'mySlot'. Au lieu d'accepter un 'int' comme argument, utilisez' sender() 'pour déterminer quel bouton est la source. –

1

[complètement révisé]

Donc, nous avons un objet Button avec plusieurs arguments qui doivent être transmis dans un slot.

class Button 
{ 
    Q_OBJECT 
public: 
    int m_arg1, m_arg2, m_arg3; 

    Button(int arg1, int arg2, int arg3) 
    { 
     m_arg1 = arg1; 
     m_arg2 = arg2; 
     m_arg3 = arg3; 
    }; 

    /// some function that emits a click signal with 2 of my arguments 
    void doSomething() 
    { 
     emit clicked (m_arg2, m_arg3); 
    } 

signals: 
    void clicked(int, int); 
}; 

Puis, plus tard:

Button *button = new Button(val1, val2, val3); 
connect(button, SIGNAL(clicked(int, int)), this, SLOT(mySlot(int, int))); 

MyReceiver::mySlot(int a1, int a2) 
{ 
    // see who called me, then use arguments 
    if (addButton == sender()) 
    { 
    x = a1 + a2; 
    } 
    else if (subButton == sender()) 
    { 
    x= a1 - a2; 
    } 
} 
+0

Quand je fais ce que vous avez suggéré, 'sender()' ou 'who' est' QSignalMapper (0x323e298) ', donc je ne comprends pas comment je devrais l'utiliser. – Dromnes

+0

Désolé; Dans ce cas, vous devez connecter directement les signaux et laisser le signalMapper à l'extérieur. Oh, attends, j'ai une idée ... – JvO

+0

J'ai l'impression de faire quelque chose de mal tout le temps. J'ai travaillé sur ce problème pendant plusieurs heures, mais rien ne fonctionne, alors j'ai simplement fait deux slots pour passer à mon code. – Dromnes