Partage
  • Partager sur Facebook
  • Partager sur Twitter

Quitter boucle while suite entrrée clavier

QMainWindow et QDialog

    9 août 2021 à 12:07:16

    Bonjour à tous,

    Je développe une interface avec Qt et je cherche à réaliser un petit subterfuge pour sortir d'une boucle while dans le cas où la condition de sortie ne serait jamais remplie.

    Je m'explique, avec mon programme, je contrôle des moteurs et parfois j'ai besoin de réinitialiser ces moteurs, sauf que parfois le contrôleur ne répond pas et mon programme reste bloqué dans la boucle while indéfiniment.

    J'ouvre mon panel de réinitialisation via une qdialog et puis j'appuie sur un bouton, classique quoi.

    Et j'aimerais, en appuyant sur ECHAP par exemple, sortir de la boucle while quand j'ai un problème avec mon contrôleur.

    J'ai donc déclaré ECHAP en QShortCut et avec le signal activated sur une méthode qui passe un booléen à true et dans ma boucle while je teste le booléen. Mais ça ne fonctionne pas.

    J'ai réussi en ajoutant qApp->processEvent dans ma boucle, sauf que l'utilisateur peut lancer d'autres méthode et c'est la porte ouverte à n'importe quoi donc je préfère éviter cette façon.

    Ci-joint le code :

    QShortcut* motorQuit = new QShortcut(QKeySequence("Escape"), dlg_motorSettings.dlg);
    QObject::connect(motorQuit, &QShortcut::activated, m_Motor, &Motion::ExitLoop, Qt::ConnectionType::UniqueConnection);
    void Motion::Reset(QString ID)
    {
    	m_exitLoop = false;
    	bool isOpen = this->open(QIODevice::ReadWrite);
    	
    	if (isOpen)
    	{
    		QByteArray message = ConstructMessageToSend(ID, RESET);
    		QString answer = SendData(message, m_timeOut);
    		QString stateMotion;
    		
                    while (stateMotion != NOT_REF || stateMotion != ESP_ERROR)
    		{
    			
    			if (m_exitLoop)
    				break;
    				
    			message = ConstructMessageToSend(ID, CURRENT_STATE);
    			answer = SendData(message, m_timeOut);
    			stateMotion = CheckStatus(answer);
    			message.clear();
    			answer.clear();
    		}
    
    		QString color = "rgb(255, 170, 0)";
    		emit updateMotionState(color);
    
    		this->close();
    	}
    	else
    		emit error("Error writing on : " + m_PortName);
    }


    Je suis preneur de la moindre idée ou conseil :)

    Merci à vous.

    • Partager sur Facebook
    • Partager sur Twitter
      9 août 2021 à 12:46:43

      Salut,

      Tu pourrais "simplement" envisager d'ajouter une condition à ta boucle while, car, ici, ta condition signifie "tant que stateMotion n'est égal ni à NOT_REF ni à ESP_ERROR", il faut faire tout ce qui est indiqué.

      La condition pourrait se transformer en "tant que stateMotion n'est égal ni à NOT_REF ni à ESP_ERROR ET que m_exitLoop est égal à false (ou n'est pas égal à  true, si tu préfère), alors il faut faire tout ce qui est indiqué ;)

      En code, cela pourrait prendre la forme de

      while( (stateMotion != NOT_REF || stateMotion!= ESP_ERROR) // #1
             && ! m_exitLooop){ // #2
          /* ce qu'il faut faire */
      }

      ou la forme de

      while (! m_exitLoop &&  // #2
             (stateMotion != NOT_REF || stateMotion != ESP_ERROR)){ #1
          /* ce qu'il faut faire */
      }

      Tu remarqueras les parenthèses qui ont été ajoutées au niveau du #1. Je les ai placées pour garantir que la priorité des opérations se fera exactement dans le sens que  je veux, car l'opérateur && (AND) est prioritaire sur l'opérateur || (OR), si bien que, si je n'avais pas ajouté ces parenthèses, l'évaluation de l'expression aurait pris les formes respectives de

      while( (stateMotion != NOT_REF || (stateMotion!= ESP_ERROR // #1
             && ! m_exitLooop) ){ // #2
          /* ce qu'il faut faire */
      }

      et de

      while ((! m_exitLoop &&  // #2
             stateMotion != NOT_REF) || stateMotion != ESP_ERROR)){ #1
          /* ce qu'il faut faire */
      }

      ce qui n'est clairement pas la même chose ;)

      • Partager sur Facebook
      • Partager sur Twitter
      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
        9 août 2021 à 12:58:27

        Salut,

        Merci pour ton retour. Je pense que c'est une bonne façon de faire en effet mais mon problème c'est que je n'arrive pas à modifier la valeur de m_exitLoop par un appui clavier

        • Partager sur Facebook
        • Partager sur Twitter
          9 août 2021 à 14:59:30

          Ah, au temps pour moi...

          Ben, dans le cas présent, comme tu as créé un raccourcis "escape" et que tu l'as connecté à la fonction membre ExitLoop de Motion, il suffit "simplement" de faire passer m_exitLoop à true dans ... la fonction ExitLoop.

          C'est "aussi simple" que cela :D

          Le raisonnement est que, quel que soit le moment où l'utilisateur enfoncera le bouton escape, il y aura un signal "onChortcutActivated(escape)" qui sera émis et ... "intercepté" par le slot ExitLoop de ta classe Motion.

          Tu peux donc profiter de l'interception pour ... modifier l'objet de type Motion qui aura intercepté ce signal, par exemple, en modifiant la valeur d'une des données membres dont cet objet dispose (m_exitLoop, en l'occurrence).

          Dans le pire des cas, cette modification va survenir tout de suite après que l'état de m_exitLoop ait été vérifié dans ta boucle, et les instructions à  exécuter dans la boucle le seront donc une dernière fois, juste avant que l'on ne revienne au point où ... on va vérifier l'état de m_exitLoop, et se rendre compte qu'il faut "quitter la boucle" ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            9 août 2021 à 15:26:59

            Oui c'est exactement ce que j'ai fait mais quand j'ouvre la fenêtre, lance la méthode Reset, la boucle while me bloque et l'appuie sur ECHAP n'y change rien de rien.

            Je suis donc passé par un Thread que j'instancie dans ma classe Moteur (communication RS232) et là ça fonctionne mais pas sûr que ce soit la façon la plus "propre" de faire

            • Partager sur Facebook
            • Partager sur Twitter

            Quitter boucle while suite entrrée clavier

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown