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

Qt Discussion :

Fermeture de l'interface et calculs lourds


Sujet :

Qt

  1. #1
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut Fermeture de l'interface et calculs lourds
    Bonjour à tous,

    j'ai un problème très simple et pourtant je n'ai trouvé nulle part une solution.
    J'ai une fenêtre Qt avec un bouton qui lance une fonction de traitement qui prends plusieurs minutes à s’exécute, le problème est que lorsque je ferme la fenêtre avant la fin du traitement la fonction ne s’arrête pas et le traitement continue en arrière plan, comment faire pour empêcher cela ?
    En gros, je voudrais que fermer la fenêtre arrête la totalité de l’exécution du code.
    Avez-vous déjà eu ce problème ?

    Merci d'avance pour l'aide,
    Matthieu

  2. #2
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Tu lances ton traitement dans un autre thread peut être ? Si oui il faudra le stopper et attendre qu'il ait terminé avant de quitter.
    Dans tous les cas tu dois stopper ton traitement quand tu détectes la fermeture de ta fenêtre (ou de l'appli). Tu peux faire ça dans void QWidget::closeEvent(QCloseEvent * event) (de ta QMainWindow), ou bien en utilisant le signal void QCoreApplication::aboutToQuit() mais comme le dit la doc c'est vraiment au dernier moment que tu vas exécuter ce code là et il n'est pas possible d'avoir une interaction utilisateur.
    De manière générale il est préférable de gérer l'arrêt de ton traitement au plus près du code qui le lance, ne serait-ce que pour l'accès à l'objet qui gère le thread par exemple.

  3. #3
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Merci de ta réponse et désolé pour cette réponse tardive.

    En gros dans mon code j'ai plein de boucle for() qui s’enchaîne quand je clique sur des boutons et donc du coup je dois créer un boolean de fermeture de ma fenêtre et le vérifier dans chaque boucle, c'est un peu "relou" à faire, non ? (mon code est assez conséquent vue que je développe une IA)

    Je pensais vraiment que Qt avais une fonction qui aurait permis de kill la totalité du code lancé par une fenêtre (en gros, fermer le processus sans aller dans le gestionnaire de tache) .

    Cordialement,
    Matthieu

    Ps: Mon thread est effectué automatiquement grâce à la fonction QObject::connect() qui relis ma fonction à l'appuis du bouton.

  4. #4
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    On peut toujours tout tuer, c'est juste qu'en général on préfère terminer proprement (en libérant des ressources, en écrivant dans des fichiers etc). Selon la tâche on peut vouloir enregistrer l'état courant et proposer de la reprendre plus tard.

    C'est sûr que selon ton code tester un booléen venant du thread principal est plus ou moins pénible, il faut décider de "paliers" réguliers dans la procédure de calcul où tester le booléen et interrompre les calculs. Pour ça tu peux envisager une petite fonction qui teste la valeur et quitte le thread, pas besoin de copier coller le code du test donc, juste à appeler ta fonction à chaque palier.

    Sinon tu dois pouvoir faire ce que tu veux avec void QThread::terminate().

  5. #5
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut Solution
    Merci pour ton aide.
    J'ai testé ça, mais ça ne fonctionne pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void MainWindow::closeEvent(QCloseEvent *event)
    {
        ui->button_start->thread()->terminate();
    }
    Je ne comprends pas pourquoi quelque chose d'aussi simple est aussi dur à faire, j'ai l'impression de louper un truc

  6. #6
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    Bonjour ce que tu fais avec ton code precedent c'est que tu termines le thread principal de ton programme,car le thread de ton bouton donc d'un element de l'UI est le thread d'UI donc le thread principal.
    Donc comme solution,il faut que tu conserves un pointeur sur le thread secondaire que tu crees et que tu lances dans ta classe Mainwindow (comme variable membre de Mainwindow) et que tu appelles dans la methode precedente MainWindow::closeEvent la methode terminate de ce pointeur .(m_pthread->terminate(); si tu as mis le pointeur sur le thread secondaire dans m_pthread)

  7. #7
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut re
    Merci de ta réponse rapide.

    Je vois ce que tu veux dire mais je vois pas trop comment le faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(ui->button_start, SIGNAL(clicked()), this, SLOT(button_start()));
    Je crois que mon thread c'est ui->button_start->thread() mais je suis pas sur.
    Tu pourrais me montrer ce qu'il faut que je mette.

    Merci d'avance.

  8. #8
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    ton connect se trouve ou ? dans la classe Mainwindow ? dans ce cas ta methode button_start cree t' elle un thread secondaire ?
    (ce qu elle devrait faire d'ailleurs )
    dans ta methode button_start de Mainwindow tu devrais creer ton thread secondaire(qui peut etre par exemple un thread derivant de QThread et dans la methode run de ce thread tu mets tout ton traitement) et recuperer un pointeur dessus que tu mets dans m_pthread et le demarrer avec start
    puis dans closeEvent tu appelles m_pthread->terminate();
    la methode connect ne cree pas de thread !!!! et comme je t'ai dit ui->button_start->thread() est ton thread principal, pas ton thread secondaire ou tu veux mettre ta tache en arriere plan

  9. #9
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    Un processus ou programme a un thread principal et des threads secondaires dans lequel tu peux mettre des traitement longs en arriere plan.Si ton programme a une interface graphique (UI) comme avec Qt, le thread principal est aussi le thread de l'interface graphique (c'est le cas de Qt) et tu crees des threads secondaires pour faire des taches en arriere plan

  10. #10
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    En gros tu es en train de me dire que je n'ai pas de thread ???
    Bah pourquoi quand je ferme ma fenêtre la méthode button_start() continue à l'executer ????
    Et surtout comment faire pour la fermer ?

    Je sais que c'est un détail mais ça m’énerve et ça me prends la tête car quand je programme j'aime quand tout fonctionne exactement comme je le souhaite.
    Je comprends pas, j'ai l'impression d’être le seul à avoir ce problème !!!

    En même temps c'est logique vue que j'utilise QCoreApplication::processEvents(); dans une fonction sleep() pour reprendre la sur l'interface.

  11. #11
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    si tu n'as pas creé de thread dans button_start tu es toujours dans le thread principal de ton application....
    et si ton traitement est vraiment long tu aurais mieux fait de creer un thread secondaire dans button_start comme je t'ai dit.
    cela necessite aussi de creer une classe de thread derivant de Qthread. (ici on peut utiliser cette maniere pour faire le thread car il y a deux methodes pour faire des threads dans Qt)

  12. #12
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    En gros, es-ce que cette ligne de code crée un thread ???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(ui->button_start, SIGNAL(clicked()), this, SLOT(button_start()));
    Et si non, pourquoi quand je ferme ma fenêtre ça coupe pas l'exécution de ma méthode button_start() ???

    Putain mais c'est pas compliqué ce que je demande, si ?

    J'ai l'impression de devenir fou !!!

    En faite vous devez me trouver trop chiant à chipoté sur un truc comme ça
    Car c'est vrai qu'à part ça mon programme fonctionne très bien et que là pour fermer mon programme j'ai juste qu'à cliqué sur le carré rouge sous Qt.

  13. #13
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    non connect ne cree pas de thread, mais relie juste un signal à un slot.
    regardes la doc de qt sur qt.io à QObject::connect
    si tu veux creer un thread tu cree par exemple une classe de thread derivant de Qthread et tu cree un thread dans ta methode button_start et tu le demarre aussi dedans et tu gardes un pointeur dessus pour le terminer (cf messages precedents)

  14. #14
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Merci, mais je veux pas un thread je veux juste pouvoir fermer tout mon programme juste en cliquant sur la croix.

  15. #15
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    mettre ton traitement long dans un thread secondaire comme evoqué plus haut resoudrait surement ton probleme....

  16. #16
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Ouais c'est surement ce que je vais faire, merci
    Par contre ça prendra plus de ressource non ?
    Et je trouve ça très bizarre que Qt n'ait pas prévue quelque chose pour ce cas là, car ça doit être fréquent comme problème, non ?

    En tout cas merci pour ton aide.

  17. #17
    Membre confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2015
    Messages : 294
    Points : 558
    Points
    558
    Par défaut
    Tu vas deporter ton traitement long dans un thread secondaire c'est tout.cela ne prend pas beaucoup plus de memoire à priori.et ca ne bloquera plus ton UI.
    quand tu as des traitements longs comme celà avec tous les environnements et/ou librairies il faut utiliser des threads secondaires, pas seulement avec Qt.

  18. #18
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Je viens de remarquer que quand je ferme ma fenêtre et que j'ai cliqué sur mon bouton, la méthode MainWindow::closeEvent() n'est pas appeler, c'est trop bizarre !!!

  19. #19
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 694
    Points : 188 894
    Points
    188 894
    Par défaut
    Citation Envoyé par Matthieu76 Voir le message
    Par contre ça prendra plus de ressource non ?
    Et je trouve ça très bizarre que Qt n'ait pas prévue quelque chose pour ce cas là, car ça doit être fréquent comme problème, non ?
    Oui, ça prendra un peu plus de ressources que de laisser l'interface geler — par contre, c'est vite compensé par la lourdeur du code qui vérifie si la fenêtre est fermée ou non dans ton code de calcul. L'impact sera négligeable (tant que tu ne crées pas un grand nombre de fils, s'entend.)

    Et Qt a bien prévu un mécanisme pour ces cas-là, un mécanisme très général, celui que Stéphane te propose : utiliser un autre fil d'exécution.

  20. #20
    Membre éclairé Avatar de Matthieu76
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2013
    Messages
    568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 568
    Points : 890
    Points
    890
    Par défaut
    Finalement j'ai juste fait un taskkill dans mon destructeur de fenêtre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System("taskkill /F /IM nom_du_programme.exe");
    Et le plus frustrant c'est que ça marche très bien.

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

Discussions similaires

  1. Interface de Calcul proche de Matlab
    Par kong.stan dans le forum Qt
    Réponses: 7
    Dernier message: 28/03/2010, 20h48
  2. Réponses: 17
    Dernier message: 01/06/2009, 04h32
  3. fermeture d'une interface java
    Par katijama dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 12/05/2009, 20h08
  4. Caractères grecs et récupération de valeur à la fermeture de l'interface
    Par Pierrot92320 dans le forum Interfaces Graphiques
    Réponses: 10
    Dernier message: 13/04/2009, 16h09
  5. [JOPTIONPANE] Fermeture de l'interface graphique
    Par meda dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 05/05/2006, 16h42

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