IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Multithreading Discussion :

Mon programme est gelé pendant mon traitement


Sujet :

Multithreading

  1. #1
    Débutant Avatar de jockyboss777
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 257
    Points : 68
    Points
    68
    Par défaut Mon programme est gelé pendant mon traitement
    Bonjour a tous !

    J'ai un petit problème sur l'un de mes projet :

    Il s'agit d'un programme qui sauvegarde des fichiers que l'utilisateur choisis, dans un QTreeView, enfin bref tout cela marche et lorsque que je lance la copie, je vois ma QProgressBar qui avance ainsi que tous les noms des fichiers copiés, mais au bout d'un court instant Windows me dit que mon programme ne répond plus (et plus rien ne bouge, donc), or il tourne encore derrière, et si j'attends quelque instant plus tard...le programme termine la copie....

    Vous avez une idée ?

    par avance merci car je ne sais pas si j'ai été très clair !?

    Jonathan

    Voici mes codes sources :

    Main.cpp
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <QApplication>
    #include <QtGui>
     
    #include "sauvegarde.h"
    #include <iostream>
    #include <stdio.h>
     
    int main(int argc, char* argv[])
    {
    	QApplication app(argc, argv);
     
    	FenSave fenetre;
    	fenetre.show();
     
    	return app.exec();
    }

    Sauvegarde.h

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #ifndef SAUVEGARDE_H
    #define SAUVEGARDE_H
     
    #include <QtGui>
    #include "ui_save.h"
    #include <iostream>
    #include <stdio.h>
    #include <time.h>
     
    enum ANNALYSE
    {
    	SAUVEGARDE,
    	COMPTAGE
    };
     
    class FenSave : public QWidget
    {
    	Q_OBJECT
     
    	public:
    		FenSave(QWidget *parent = 0);
    		~FenSave();
     
    	public slots:
    		void ModifList(QModelIndex modif);
    		void VerifCopie();
     
    	protected:
    		void LettreLecteur();
    		void CheminSauvegarde();
    		void CompterFichier();
    		void CopierFichier();
    		void VerifDossier(QString path, ANNALYSE type);
     
    		Ui::FenSave ui;
    		QStringList listToSave;
    		QString dossierDate;
    		int nbrFichier;
    		int nbrDossier;
    		int nbrFichierCopie;
    		int nbrDossierCopie;
     
    		QFileSystemModel *model;
    };
     
    #endif

    Sauvegarde.cpp

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    #include "sauvegarde.h"
     
    FenSave::FenSave(QWidget *parent) : QWidget (parent)
    {
    	ui.setupUi(this);
    	model = new QFileSystemModel;
    	nbrDossier = 0;
    	nbrFichier = 0;
    	nbrFichierCopie = 0;
    	nbrDossierCopie = 0;
     
    	time_t timestamp;
    	struct tm * t;
    	timestamp = time(NULL);
    	t = localtime(&timestamp);
    	dossierDate = QVariant(t->tm_mday).toString() + "." + QVariant(t->tm_mon).toString() + "." + QVariant(t->tm_year+1900).toString();
     
     
    	//Initialisation
    		LettreLecteur();
    		CheminSauvegarde();
     
    	//CONNECTIONS
    		QObject::connect(ui.saveDir, SIGNAL(clicked(const QModelIndex)), this, SLOT(ModifList(const QModelIndex)));
    		QObject::connect(ui.startSave, SIGNAL(pressed()), this, SLOT(VerifCopie()));
     
    }
     
    FenSave::~FenSave()
    {
    	delete model;
    }
     
    //========== SLOTS PERSO ==========
     
    void FenSave::ModifList(const QModelIndex modif)
    {
    	QString stringIndex = model->filePath(modif);
     
    	if(listToSave.count(stringIndex))
    	{
    		listToSave.removeAll(stringIndex);
    	}
    	else
    	{
    		listToSave.append(stringIndex);
    	}
    }
     
    void FenSave::VerifCopie()
    {
    	QString resume;
     
    	for(int i=0; i < listToSave.size(); i++)
    	{
    		resume += "   * " + QVariant(i+1).toString() + " : " + listToSave.at(i) + "\n";
    	}
     
    	 QMessageBox msgBox;
    	 QPushButton *OKButton = msgBox.addButton("Continuer", QMessageBox::AcceptRole);
    	 msgBox.addButton("Annuler", QMessageBox::RejectRole);
     
    	if(ui.format->checkState() == Qt::Checked)
    		msgBox.setText("Sauvegarder les dossiers et fichiers suivant :\n" + resume + "\nATTENTION LA CASE 'Formater' EST COCHEE, ce qui signifie que le périphérique selectionné sera FORMATER ET TOUTES LES DONNEES SERONT PERDU !\n" + "\nLe comptage des fichier peut prendre un certain temps, cela depend des fichiers/dossiers choisient.\nPatientez, la copie démarrrera a la fin de cette étape.\nMême si Windows vous informe que le programme a céssé de fonctionner, patientez ce n'est pas le cas.");
    	else
    		msgBox.setText("Sauvegarder les dossiers et fichiers suivant :\n" + resume + "\n" + "\nLe comptage des fichier peut prendre un certain temps, cela depend des fichiers/dossiers choisient.\nPatientez, la copie démarrrera à la fin de cette étape.\nMême si Windows vous informe que le programme a céssé de fonctionner, patientez ce n'est pas le cas.");
     
    	 msgBox.exec();
     
    	if(msgBox.clickedButton() == OKButton)
    	{
    		if(ui.format->checkState() == Qt::Checked)
    		{
    			//Formatage
    		}
    		CompterFichier();
    		ui.progress->setMaximum(nbrFichier + nbrDossier);
    		CopierFichier();
    	}
    }
     
    //========== FONCTION NORMALE ==========
     
    void FenSave::LettreLecteur()
    {
    	QFileInfo *file = new QFileInfo;
    	QFileInfoList *perif = new QFileInfoList;
    	*perif = QDir::drives();
    	ui.info->append("Périphériques trouvés : " + QVariant(perif->size()).toString());
     
     
    	for(int i=0; i < perif->size(); i++)
    	{
    		*file = perif->at(i);
    		ui.letter->addItem(file->path());
    	}
     
    }
     
    void FenSave::CheminSauvegarde()
    {
    	model->setRootPath("C:\\");
     
    	ui.saveDir->setModel(model);
     
    	ui.saveDir->setAnimated(false);
        ui.saveDir->setIndentation(20);
        ui.saveDir->setSortingEnabled(true);
        ui.saveDir->sortByColumn(0, Qt::AscendingOrder);
    	ui.saveDir->setColumnWidth(0, 200);
    }
     
    void FenSave::CompterFichier()
    {
    	nbrFichier = 0;
    	nbrDossier = 0;
     
    	for(int i=0; i < listToSave.size(); i++)
    	{
    		VerifDossier(listToSave.at(i), COMPTAGE);
    	}
     
     
    	ui.info->append("Nombre de fichiers totals trouvés : " + QVariant(nbrFichier).toString());
    	ui.info->append("Nombre de dossiers totals trouvés : " + QVariant(nbrDossier).toString());
    }
     
    void FenSave::CopierFichier()
    {
    	nbrFichierCopie = 0;
    	nbrDossierCopie = 0;
     
    	for(int i=0; i < listToSave.size(); i++)
    	{
    		VerifDossier(listToSave.at(i), SAUVEGARDE);
    	}
     
     
    	ui.info->append("Nombre de fichiers totals <strong>copiés</strong> : " + QVariant(nbrFichier).toString());
    	ui.info->append("Nombre de dossiers totals <strong>copiés</strong> : " + QVariant(nbrDossier).toString());
    	ui.info->append("<hr />");
     
    }
     
    void FenSave::VerifDossier(QString path, ANNALYSE type)
    {
     
    	QFileInfo test(path);
     
    	if(test.isDir())
    	{
    		if(type == SAUVEGARDE)
    		{
    			//Création du Dossier sur le périphérique
    			QString arborescence = ui.letter->currentText() + dossierDate + "/" + QString(path).remove(0, 3);
    			if(QDir().mkpath(arborescence))
    				ui.info->append("<em>Création de  : " + arborescence + "</em>");
    			else
    				ui.info->append("<em>Impossible de créer : " + arborescence + ", le dossier existe peut être déja.</em>");
    		}
     
    		QDir dossier(path);
    		QFileInfoList fileList;
     
    		fileList = dossier.entryInfoList((QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot), (QDir::Name | QDir::DirsFirst));
     
    		for(int i=0; i < fileList.size(); i++)
    		{
    			if(fileList.at(i).isDir())
    			{
    				switch(type)
    				{
    					case COMPTAGE:
    						nbrDossier++;
    						break;
     
    					case SAUVEGARDE:
    						nbrDossierCopie++;
    						break;
    				}
    				VerifDossier(fileList.at(i).absoluteFilePath(), type);
    			}
    			else if(fileList.at(i).isFile())
    			{
    				switch(type)
    				{
    					case COMPTAGE:
    						nbrFichier++;
    						break;
     
    					case SAUVEGARDE:
    						nbrFichierCopie++;
    						QString arboFile = ui.letter->currentText() + dossierDate + "/" + QString(fileList.at(i).absoluteFilePath()).remove(0, 3);
    						if(QFile(fileList.at(i).absoluteFilePath()).copy(arboFile))
    							ui.info->append("<em>Création de  : " + arboFile + "</em>");
    						else
    							ui.info->append("<em>Impossible de créer : " + arboFile + "</em>");
    						break;
    				}
    			}
     
    			if(type == SAUVEGARDE)
    				ui.progress->setValue(nbrFichierCopie + nbrDossierCopie);
    		}
    	}
    	else if(test.isFile())
    	{
    		switch(type)
    		{
    			case COMPTAGE:
    				nbrFichier++;
    				break;
     
    			case SAUVEGARDE:
    				nbrFichierCopie++;
    				break;
    		}
     
    		if(type == SAUVEGARDE)
    			ui.progress->setValue(nbrFichierCopie + nbrDossierCopie);
    	}
    }

    Encore merci !

  2. #2
    Membre confirmé
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Points : 533
    Points
    533
    Par défaut
    oui c'est normal, tout traitement un peu lourd n'est pas sensé être fait directement dans les méthodes de ta GUI, car ça bloque la boucle d'évènement principale.

    Il faut utiliser un thread pour effectuer tes traitements en même temps que la GUI continu sa vie dans son coin...

  3. #3
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Si c'est juste un blocage au niveau de l'exécution et non pas un bug qui traîne quelque part tu peux utiliser la fonction
    QApplication::processEvents ( int maxtime )

    c'est l'équivalent de DoEvent en C++ et en VB.Net

  4. #4
    Débutant Avatar de jockyboss777
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 257
    Points : 68
    Points
    68
    Par défaut
    Merci haraeledil, c'est bien ce que je pensé, il y a un moyen de faire cela avec Qt (on sait jamais !?) et/ou alors tu aurais une petite aides sur les thread car je n'en n'ai jamais fais !?

    Sinon il faut que je mette la fonction qui fais une copie dans un thread ou alors chaque récursivité a son thread ?

    Encore merci pour ton aides !
    Jonathan


    Edit : Zut ! e temps que je lise et écrive le message je n'ai pas vu ta réponse 3asfoura, ou je met ta méthode ? Et je met combien de temps car je n'en n'ai pas la moindre idée du temps d'éxécution, tout cela dépend des fichier choisie par l'utilisateur

    Merci pour ta fct je vais essayer !

  5. #5
    Membre confirmé
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Points : 533
    Points
    533
    Par défaut
    Bien sur, faire un thread basique pour effectuer un traitement est très simple avec Qt.

    Tu crée une classe qui hérite de la classe QThread, tu met ton traitement à faire en ré-implémentant la méthode run().

    Après dans ta GUI, tu le lance avec le slot start(), et il émet un signal finished() quand c'est terminé.

  6. #6
    Débutant Avatar de jockyboss777
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 257
    Points : 68
    Points
    68
    Par défaut
    D'accord donc je créer une classe pour le GUI et une classe (qui hérite de QThread pour la copie ?

  7. #7
    Membre confirmé
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Points : 533
    Points
    533
    Par défaut
    oui c'est ça.

    Je suppose que ton code de copie était dans un slot de ta classe gui actuellement, donc si oui, tu bouge tout ça dans la méthode run() de ta classe héritant de QThread, et dans ton slot, tu crée ton thread, tu lui passe les truc dont il pourrait avoir besoin pour travailler (ça peut se faire directement par le constructeur), et après tu le lance.

    Après tu n'as plus qu'à brancher un autre slot sur le signal finished() de ton thread, et le tour est joué.

  8. #8
    Débutant Avatar de jockyboss777
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 257
    Points : 68
    Points
    68
    Par défaut
    En fait a copie n'est pas dans un slot mais ce n'est pas important.
    Sinon uand tu dis run() tu donne juste un exemple ou c'est obligatoirement la fonction qu'il faut réimplante ?

    Sinon aprs avoir séparer en deux classe je pourrai toujours faire :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    ui.info->append("Hello World");
    Pour afficher qqch dans la "console" (en fait c'est QTextEdit) du programme ?


    Et un grand merci pour tes réponse

  9. #9
    Membre confirmé
    Avatar de haraelendil
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2004
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2004
    Messages : 283
    Points : 533
    Points
    533
    Par défaut
    Un petit tour sur la doc de QThread -> QThread

    C'est obligatoirement une méthode run() qu'il faut ré implémenter et qui sera lancé après appel à start().

    Sinon, ce ne sera plus possible, mais tu peux toujours te créer un signal dans ta classe thread que tu emmétras à chaque fois que tu veux afficher un message, et la gui récupérera se message et l'affichera par exemple.

  10. #10
    Débutant Avatar de jockyboss777
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 257
    Points : 68
    Points
    68
    Par défaut
    Ok d'accord ! parfait
    Merci pour ton aide, je m'excuse pour la question pourri alors que tout était dans la doc...

    Bon ben...au boulot et encore merci pour ton aide !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/02/2015, 17h49
  2. Mon programme est incapable de reconnaitre hypermedia
    Par firasovich dans le forum Général Java
    Réponses: 0
    Dernier message: 04/04/2014, 18h07
  3. mon programme est très lent
    Par kawther dans le forum Images
    Réponses: 4
    Dernier message: 08/04/2010, 12h28
  4. Est ce que mon programme est juste ?
    Par autoin dans le forum C
    Réponses: 6
    Dernier message: 25/01/2008, 17h06
  5. Mon programme est considéré comme un trojan -_-'
    Par peijnoob dans le forum Windows
    Réponses: 3
    Dernier message: 21/03/2007, 14h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo