2012-03-25 4 views
1

J'ai le code suivant:Comment utiliser un processus (QProcess) dans un nouveau thread (QThread)?

void Processmethod() 
{ 

    QDialog *ProcessMessage = new QDialog;  
    Ui::DialogProcessMessage Dialog;    
    Dialog.setupUi(ProcessMessage);    
    ProcessMessage->setModal(true); 
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose); 
    ProcessMessage->show(); 

    qApp->processEvents(); 

    processmethodONE(); 
    processmethodTWO(); 
    processmethodTHREE();     
} 

void processmethodONE() 
{ 
    QString ProcessCommand = "w8 " + blablubli";    

    Prozess.setWorkingDirectory(Path);   //QProcess "Prozess" is globaly defined 
    Prozess.setStandardOutputFile(Path);  //in my class 

    QThread* thread = new QThread; 
    Prozess.moveToThread(thread); 
    Prozess.start(ProcessCommand); 


while(!Prozess.waitForFinished(2000)) 
    { 
     std::cerr << "Process running " << std::endl; 
    } 

QProcess::ExitStatus Status = Prozess.exitStatus(); 

if (Status == 0) 
{ 
    std::cout << "File created!" << std::endl; 
} 
} 

Dans ce code source, je tente d'ouvrir une boîte de dialogue pop-up avant que certains processus commencent. Le problème est que la boîte de dialogue n'est pas cliquable, mais dans la boîte de dialogue, je veux créer un bouton pour abandonner la méthode en cours. Comme vous pouvez le voir, j'ai essayé d'utiliser QThread pour lancer le (s) processus dans un autre thread, mais je n'arrive toujours pas à cliquer sur le dialogue. De plus, si j'ouvre mon application (GUI) avec le fichier "application/x-executable", le contenu des dialogues est manquant lors de l'activation de la méthode ci-dessus. Comment puis-je résoudre ces problèmes? Où ai-je tort? salutations

+1

J'ai quelques questions ... 1) Comment appelez-vous 'Processmethod()'? 2) Pourquoi pensez-vous que vous devez créer un QThread et y insérer le QProcess? Et aussi, pourquoi ne lancez-vous pas le nouveau QThread? 3) Utilisez-vous ce QProcess global pour tous vos 'processmethodX()'? – jdi

+0

cela ne correspond pas à la question, mais je vous suggère d'écrire des noms de variables dans _lowerCamelCase_. C'est très lisible rapidement. Cependant, je suis d'accord avec JDI, besoin de plus d'informations pour répondre. – jalone

+0

Il n'est généralement pas nécessaire d'exécuter QProcess dans un thread, car son API ne bloque pas, sauf si vous utilisez les méthodes waitForStarted/Finished. –

Répondre

2
void processmethodONE() 
{ 
    QThread* thread = new QThread; 
    Prozess.moveToThread(thread); 
    Prozess.start(ProcessComand); 

Ici, vous avez déplacé le processus QProcess vers un autre processus. Mais alors vous appelez start() dessus. Ce n'est déjà pas sûr pour les threads.

while(!Prozess.waitForFinished(2000)) 
{ 
    std::cerr << "Process running " << std::endl; 
} 

Cela bloque et rend l'utilisation d'un thread inutile. En outre, ce n'est pas sûr pour les threads.

Vous devriez plutôt pas utiliser des fils mais:

  1. supprimer le waitForFinished() appeler
  2. Connecter le fini() et erreur() signaux du QProcess aux emplacements qui commencent alors l'étape suivante, à savoir processMethodTWO.

Je déconseille également de réutiliser des objets QProcess et en crée un nouveau pour chaque étape.

+0

Ok, je l'ai d'abord essayé. J'ai déjà pour chaque processus un objet QProcess différent - c'est ce que je voulais dire avec mon premier commentaire. – Streight

+0

J'ai essayé maintenant de connecter le signal finish() du premier processus "Prozess" avec la seconde méthode "processmethodTWO()" avec connect (Prozess, SIGNAL (finished()), processmethodTWO(), (SLOT (start()))); , mais j'ai l'erreur "utilisation invalide de l'expression vide". -> probablement un noob échoue :). – Streight

1

Bien que je ne comprends toujours pas entièrement votre exemple de code récemment mis à jour, je pense que ce pourrait être votre problème:

while(!Prozess.waitForFinished(2000)) 
    { 
     std::cerr << "Process running " << std::endl; 
    } 

Où que vous appelez vraiment dans votre code d'origine bloque en attendant Prozess pour finir.

Utilisez une instance QProcess neuve pour chacun d'eux et connectez leurs signaux finished() à un SLOT qui sera appelé quand ils auront fini. Ne les interrogez pas manuellement et ne les bloquez pas. Cela vous permettra de vous débarrasser complètement de QThreads.

+0

J'ai un global pour chaque processus, cela signifie 'un QProcess Prozess pour processmethodONE();', 'un QProcess Prozess2 pour processmethodTWO();' ... La méthode 'waitForFinished()' dont j'ai besoin parce que les processus ont besoin de temps et le processus précédent doit toujours être terminé avant le prochain démarrage. – Streight

+0

Si c'est le cas, alors vous devez faire une approche différente. Votre exemple suggère que tous les processus ont pu fonctionner en même temps. Si vous avez besoin de les exécuter dans l'ordre, alors vous pouvez chaîner le signal 'finished()' de l'un à l'emplacement 'start()' de l'étape suivante, et ainsi de suite. – jdi

+0

Ou, vous pouvez simplement créer un QThread personnalisé qui exécute toutes vos commandes en utilisant des appels système synchrones de niveau inférieur C++, car QProcess n'est plus un avantage. Ensuite, utilisez simplement le signal QThread finished() pour annoncer que tout est terminé. – jdi

Questions connexes