Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1195 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [Résolu][Qt] QProcess lancés en boucle - started() et finished()

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu][Qt] QProcess lancés en boucle - started() et finished()

n°1442850
blacksad
Posté le 15-09-2006 à 10:03:45  profilanswer
 

Bonjour,
Contexte : j'ai une application Qt/C++ qui me permet de copier des fichiers dans un répertoire que j'ai choisi : j'ai une interface où je rentre le nom du dossier qui contiendra mes fichiers copiés (via QFileDialog::getExistingDirectory()), et un tableu à deux colonnes où je mets d'un coté le nom du fichier à copier ( via QFileDialog::getOpenFileName() ) et de l'autre son état d'avancement. Pour la copie proprement dite, j'appelle un programme C++ externe (nommé ici "copy" ) que je lance en tant que processus (je pourrais faire autrement mais le but de cette application est justement d'apprendre à gérer les processus...). J'ai donc une boucle qui me parcourt mon tableau, et me lance un nouveau processus "copy" tant qu'il y a des fichiers à copier. Jusque là, tout va bien.
Là où ça se corse, c'est pour l'affichage de l'état d'avancement de chaque processus. Au début j'avais fait ça :  

Code :
  1. void CopyBoard::setSource()
  2. {
  3.     QString source = QFileDialog::getOpenFileName(this);
  4.     listSource->insert(listSource->size(),source);
  5.    
  6.     currentIndice++;
  7.     int i = currentIndice;
  8.     QTableWidgetItem *tableSource = new QTableWidgetItem((*listSource)[i]);
  9.     tableSource->setText((*listSource)[i]);
  10.     table->setItem(i,0,tableSource);
  11.     setEtatQueue();       
  12. }
  13. /*
  14. Affiche un explorateur de fichier où l'on chosit le dossier qui contiendra les copies de
  15. fichier. Affiche le chemin du dossier dans un QLineEdit.
  16. */
  17. void CopyBoard::setDestRep()
  18. {
  19.     QString destRep = QFileDialog::getExistingDirectory(this);
  20.     line->setText(destRep);
  21. }   
  22. /*
  23. Met le fichier désigné par "currentIndice" dans l'état "En attente".
  24. La copie n'a pas été commencée.
  25. */
  26. void CopyBoard::setEtatQueue()
  27. {
  28.     QString etat = "En attente";
  29.     QTableWidgetItem *tableEtat = new QTableWidgetItem(etat);
  30.     tableEtat->setText(etat);
  31.     cout << "attente : " << currentIndice << endl;
  32.     table->setItem(currentIndice,1,tableEtat);
  33.     table->show();
  34. }
  35. /*
  36. Met le fichier désigné par "currentIndice" dans l'état "En cours".
  37. La copie a commencé.
  38. */
  39. void CopyBoard::setEtatRunning()
  40. {
  41.     QString etat = "En cours";
  42.     QTableWidgetItem *tableEtat = new QTableWidgetItem(etat);
  43.     tableEtat->setText(etat);
  44.     cout << "running : " << currentIndice << endl;
  45.     table->setItem(currentIndice,1,tableEtat);
  46.     table->show();
  47. }
  48. /*
  49. Met le fichier désigné par "currentIndice" dans l'état "Terminé".
  50. La copie est terminée.
  51. */
  52. void CopyBoard::setEtatEnd(int reussite)
  53. {
  54.     QString etat;
  55.     if (reussite) {etat = "Terminé avec succès";}
  56.     else {etat = "ECHEC !";}
  57.     QTableWidgetItem *tableEtat = new QTableWidgetItem(etat);
  58.     tableEtat->setText(etat);
  59.     cout << "Fin : " << currentIndice << endl;
  60.     table->setItem(currentIndice,1,tableEtat);
  61.     table->show();   
  62. }
  63. void CopyBoard::copier()
  64. {
  65.     QString repDest = line->text();
  66.     QString program = "[repertoire du programme de copie]/copy";
  67.          
  68.     for(int i=0; i<listSource->size(); i++)
  69.     {
  70.      currentIndice = i;
  71. QString source = (*listSource)[i];
  72. QString dest = repDest + source.right(source.length()-source.lastIndexOf('/')-1);
  73. //Appel du programme "copy".
  74. QStringList arguments;
  75. arguments << source << dest;
  76. QProcess *myProcess = new QProcess(this);
  77. myProcess->start(program,arguments);
  78. connect(myProcess, SIGNAL(started()), this, SLOT(setEtatRunning()));
  79. connect(myProcess, SIGNAL(finished(int)), this, SLOT(setEtatEnd(int)));
  80. //myProcess->waitForFinished();
  81.      }   
  82. }


 
Mais le problème eqt au niveau du lancement des signaux lignes 87 et 88. En fait le programme exécute la boucle de la ligne 74 autant de fois qu'il y a de fichiers, puis envoie les signaux started(), puis les signaux finished(), et à ce moment là, mon currentIndice, qui désigne le fichiers en cours de traitement (le ième tour de boucle en fait), est le nombre de fichiers - 1. Et comme les fonctions setEtatRunning() et setEtatEnd() font leurs modifications dans la case désignée par currentIndice, et bien toutes les modifs se font sur la dernière ligne...
J'ai ensuite tenté de "bloquer" ce currentIndice, en ajoutant myProcess->waitForFinished(); à la ligne 90. Les processus se sont bien lancé un par un, les signaux ont bien été envoyés aux bons moments, mais waitForFinished() gèle l'affichage du QWidget, si bien que les modification des changement d'état sont au bon endroit, mais modifiées que lorsque tout est fini...
Dernière tentative, j'ai essayé de remettre à 0 mon currentIndice une fois qu'il a fini tout ses tours de boucle, comme ça la méthode setEtatRunning() se lance avec les bons indices, j'ai fait pareil pour setEtatEnd() , mais les indices ainsi bricolés ne correspondent pas forcément aux indices des processus qui viennent de se terminer : c'est forcément la ligne une qui aura la première l'état "Terminé avec succès", même si la copie du premier fichier est celle qui dure le plus longtemps.
 
"Et la question dans tout ça, c'est quoi ?"
En fait mes questions sont :
Est-il possible d'identifier quel processus envoie le signal started() ou finished() ? (Comme ça je saurais quelle ligne il faut modifer dans mon tableau)
Actuellement les processus se lancent en parallèle, est il possible de les lancer en série ? (Comme pourrai incrémenter mon currentIndice en sachant qu'un processus ne "doublera" pas l'autre)
Toute autre idée, piste, suggestion pour résoudre mon problème et/ou améliorer mon programme est la bienvenue  :)  
 
Merci d'être arrivé jusque là.
 
Blacksad.


Message édité par blacksad le 19-09-2006 à 12:46:11
mood
Publicité
Posté le 15-09-2006 à 10:03:45  profilanswer
 

n°1444559
sashock
Posté le 19-09-2006 à 11:50:30  profilanswer
 

j'ai pas tout lu en détail mais déja si tu connectais ton slot setEtatRunning() AVANT de faire myProcess-->Start() ca serait mieux non?

n°1444578
blacksad
Posté le 19-09-2006 à 12:46:20  profilanswer
 

Merci pour ta réponse mais en fait on m'a aidé aussi sur un autre forum et j'ai fini par m'en sortir : http://qtfr.org/forum/viewtopic.php?pid=12185#p12185
J'ai pas édité ce topic parce que je pensais qu'il était parti aux oubliettes...  
Merci quand même.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [Résolu][Qt] QProcess lancés en boucle - started() et finished()

 

Sujets relatifs
Récupérer le Full Name d'un utilisateur réseau en VBA [Résolu]selection Listbox avec multiselected [résolu]
[RESOLU] Evénement onclick()[Résolu] Mon script d'ouverture de pop-up ne doit pas être bon !
[Access] Affichage des nombres dans les reports Access [Résolu][RESOLU] Dégradé 100% hauteur et largeur ?
pb de requete SQL (enfin je crois) dans access [résolu]Probleme de boucle en perl
Supprimer ligne Excel vba [résolu][Batch Dos][Résolu] cacher l'invite de commande
Plus de sujets relatifs à : [Résolu][Qt] QProcess lancés en boucle - started() et finished()


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR