2017-06-05 1 views
1

J'ai toujours du mal à faire fonctionner ce que je m'attendais.Qt-Utilisation de signaux et de slots avec des threads différents

J'ai un projet Qt que je voudrais mettre à jour en fonction des états du signal de différents threads. Mon thread graphique principal devrait démarrer un thread de travail en appuyant sur un bouton de démarrage.

Le thread de travail devrait alors exécuter une fonction qui interroge continuellement les variables appartenant à une autre classe qui sont mises à jour par un thread différent (j'utilise des bibliothèques portaudio). Il devrait alors déclencher un signal (sendNewSig) qui est connecté à un slot (DrawData) dans ma classe GUI.

Le problème est le blocage du programme lorsque j'appuie sur le bouton de démarrage. Je crois qu'il me manque quelques étapes essentielles pour commencer à exécuter le thread de travail. En appelant updater-> PollSignal() comme ceci quand on clique sur le bouton start, je m'attends à ce qu'il s'exécute dans un nouveau thread mais peut-être pas. J'ai montré ci-dessous des parties du code qui, je l'espère, suffiront à faire passer mon idée.

Un grand merci à l'avance pour toute aide

Dans GUIApp.cpp

AudioGuiApplication::AudioGuiApplication(QWidget *parent) 
: QMainWindow(parent) 
{ 
    ui.setupUi(this); 

    //...... other stuff 

    thread = new QThread(this); 
    updater = new GUIUpdater(&audio_processor); 
    updater->moveToThread(thread); 

    connect(updater, SIGNAL(sendNewSig(string)), this, SLOT(DrawData(string))); 

    connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater())); 

    actionText->setPlainText("Press Start to begin "); 
} 

void AudioGuiApplication::on_startButton_clicked() 
{ 
    updater->PollSignal(); 
} 

Dans GUIUpdater.cpp`

void GUIUpdater::PollSignal() 
{ 
    string str; 

    while (!ap->IsNewDataFound()) 
    { 
     emit sendNewSig(str); 
     ap->SetNewSigFound(false); 
    } 
}` 

Répondre

2

Vous appelez la fonction PollSignal du thread principal/gui directement.

Je pense que la meilleure façon de l'exécuter dans le fil souhaité est d'utiliser le mécanisme de fente de signal & avec un ensemble unique tiré QTimer sans retard (0 représente 0 millisecondes):

void AudioGuiApplication::on_startButton_clicked() 
{ 
    QTimer::singleShot(0, updater, &GUIUpdater::PollSignal); 
} 

Par le chemin: vous devriez envisager de passer au "new" connect syntax qui ne dépend pas des macros et permet la validation de type à la compilation à la place.

+1

Merci. J'ai essayé ça. L'interface graphique n'est pas mise à jour comme je l'espérais cependant. Comme mon signal est connecté à mon slot comme ceci: connect (updater, SIGNAL (sendNewSig (chaîne)), this, SLOT (DrawData (chaîne))); Quand j'émet sendNewSig (str) dans ma fonction d'interrogation, ne devrait-il pas appeler la fonction DrawData de ma classe GUI avec str comme paramètre? DrawData n'est pas un slot tho, juste une fonction membre normale – Engineer999

+0

'DrawData' * doit * être un emplacement pour l'ancienne syntaxe' connect'. En outre, vous devez enregistrer 'string' dans les mécanismes de réflexion de Qt: http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType Sinon, Auto/QueuedConnection (ce qui est dans votre cas) ne sera pas travail. J'ai supposé que ce n'était pas le problème, parce que la question n'était pas à ce sujet :) – krzaq

+0

chaîne de registre dans les mécanismes de réflexion? Je ne suis pas sûr de comprendre. Comment et où ferais-je cela? Merci – Engineer999