2009-12-31 4 views
3

Je suis en train d'apprendre Qt et j'ai une question très simple.Question sur les slots Qt et les appels multiples

S'il existe une variable (fonction de portée) dans un emplacement et que l'emplacement est appelé plusieurs fois, chaque fois avant le dernier appel (est-ce encore possible?), La variable sera-t-elle écrasée? Dans le sens où, si l'emplacement est appelé avant que l'exécution précédente ne soit retournée, cela ne causerait-il pas des erreurs?

Merci.

Répondre

1

Si vous utilisez vraiment des variables d'étendue de fonction, cela ne devrait pas avoir d'importance. Exemple:

class WheelSpinner : public QThread 
{ 
Q_OBJECT; 
public: 
    WheelSpinner(QObject* receiver, const char* slot) 
    { 
     connect(this, SIGNAL(valueChanged(int)), receiver, slot, 
       Qt::DirectConnect); 
    } 

    void run() 
    { 
     for (int i = 0; i < 100000; ++i) 
     { 
      emit (valueChanged(i)); 
     } 
    } 

public signals: 
    void valueChanged(int value); 
}; 

class ProgressTracker : public QObject 
{ 
Q_OBJECT; 
public: 
    ProgressTracker() { } 

public slots: 
    void updateProgress(int value) 
    { 
     // While in this function, "value" will always be the proper 
     // value corresponding to the signal that was emitted. 
     if (value == 100000) 
     { 
      // This will cause us to quit when the *first thread* that 
      // emits valueChanged with the value of 100000 gets to this point. 
      // Of course, other threads may get to this point also before the 
      // program manages to quit. 
      QApplication::quit(); 
     } 
    } 
}; 

int main(int argc, char **argv) 
{ 
    QApplication app(argc, argv); 
    ProgressTracker tracker; 
    WheelSpinner spinner1(&tracker, SLOT(updateProgress(int ))); 
    WheelSpinner spinner2(&tracker, SLOT(updateProgress(int ))); 
    WheelSpinner spinner3(&tracker, SLOT(updateProgress(int ))); 

    spinner1.run(); 
    spinner2.run(); 
    spinner3.run(); 

    return (app.exec()); 
} 
+0

Donc dans ce cas, vous dites que si le même objet WheelSpinner (disons spinner2) appelle updateProgress pour i, et que l'appel i-1th n'est pas encore terminé, il fonctionnera bien? –

+1

@ trex279: Tout d'abord, avec une connexion directe, si spinner2 appelle updateProgress pour i, il ne continuera pas tant que la fonction updateProgress n'est pas terminée. Cette partie est séquentielle. Si, toutefois, spinner1 s'exécute pour i + 1 alors que spinner2 exécute toujours la même fonction pour i, les deux s'exécuteront correctement. –

2

Oui si les appels proviennent de différents threads ET que vous utilisez une connexion directe. Si vous utilisez des connexions en file d'attente, les appels d'emplacement seront exécutés l'un après l'autre sur la boucle d'événements qui est exécutée sur le thread auquel appartient votre objet récepteur. (éditez grâce au commentaire d'Idan K).

Checkout Signal and slots la connexion en attente ou QMutexLocker pour résoudre votre problème.

+1

Je crois que les connexions en file d'attente sont exécutées sur la boucle d'événements à laquelle le QObject est attaché. Ainsi, par exemple, si vous créez un QObject dans QThread :: run(), son slot sera traité dans le contexte de QThread. –

+0

C'est vrai! Je vous remercie! – fulmicoton

+0

Je ne suis pas d'accord, mais il n'y a peut-être pas assez d'informations pour le dire à coup sûr. S'il s'agit d'une variable * function-scope *, rien ne doit l'écraser, même dans des threads différents qui s'exécutent simultanément. Dans ce cas, cela devrait fonctionner correctement. Toutefois, s'il s'agit d'une référence de fonction-portée ou d'une variable de pointeur, les données source peuvent avoir changé, ce qui peut entraîner des problèmes. –

1

Tant que la fonction est reentrant il n'y a pas de problème.

+2

Une note importante est que QObject :: sender() est _not_ reentrant. – Macke