Répondre à la discussion
Affichage des résultats 1 à 3 sur 3

Qt en C++, appui sur une touche du clavier ?



  1. #1
    dje8269

    Qt en C++, appui sur une touche du clavier ?


    ------

    Bonjour à tous,

    Je m'initie à Qt après avoir lue 2 fois les cours de "open classroom" . A la base je viens du C et du monde des microcontrôleurs.

    Ce langage est pour le moins, pas très intuitif au départ . J’espère que cela vient en s’exerçant car c'est très intéressant.

    Venant du C la langage la logique n'est pas du tout la même que la POO.

    Je rentre dans le vif du sujet.

    Je souhaite détectée l'appui sur une touche du clavier disons le "Z" ( car les fléches ne fonctionnent pas apparemment), pour envoyer un message sur le port série afin de faire avancer un robot.
    Voila ou je bloque, je souhaiterais faire une action lors de l'appui sur une touche et répétée cette action tant que la touche est enfoncée.
    Mais quand la touche n'est plus enfoncée (mais qu'elle l'a été) faire une autre action.

    Touche "Z" enfoncée : envoie d'un ordre par le port série. par boucle toute les 100ms afin de faire avancer le robot(avec la fonction repeat).

    Touche "Z" relâchée, envoie d'un ordre pour envoyer une commande afin arrêter les moteurs.

    Le problème c'est que la méthode KeyPressEvent, fait un repeat des autres méthodes de keyreleaseEvent par exemple . Tout comme "pushbutton".

    Avez vous une solution pour parer à ce probléme ?

    J'avais trouvé une solution de contournement pour la fonction "pushbutton" avec " isDown". Mais avec les touches du clavier il n'y a pas cette option de disponible.

    Voici mon code qui me permet seulement de faire des tests pour le moment, histoire de mettre au point le comportement parfait .
    Ce code affiche donc alternativement GO et STOP quand je laisse la touche "Z" enfoncée.
    Alors que je souhaiterais que des "GO" et des que je la relâche un "STOP" .

    Code:
    /**************************************************************************
                        méthodes
    **************************************************************************/
     
    void MainWindow::keyPressEvent(QKeyEvent *ev)
    {
     
        if (ev->key() == Qt::Key_Z)
        {
            qDebug()<<"GO";
        }
    }
     
    void MainWindow::keyReleaseEvent(QKeyEvent *)
    {
        qDebug()<<"STOP";
    }

    Sinon j'avais pensé a faire imiter l'appui sur un bouton quand on appui sur une touche ? mais je sais pas si ca existe ? Du genre j’appuie sur "Z" et ça enfonce le bouton ainsi je pourrais me servir de la routine du bouton plutôt que celui de la touche ?


    J'ai cru tenir une solution mais finalement elle n'est pas optimale. Je la partage quand même, cela pourra éventuellement vous aidez à m'aider ( ou pas) .

    Mon idée était d'utiliser l'attribut "isAutoRepeat" qui permet de savoir si l'action vient de premier événement ou d'une répétition de l’événement.
    Donc en gros donc la méthode released .

    Si c'est du à une répétition d’événement ( quand la touche est enfoncée) alors je ne fais rien, car l'action est causé par le repeat et non car on a lâché la touche.
    Par contre si le relâchement est du au premier relâchement et donc pas par un repeat , c'est que la touche à été relâcher donc j'effectue une tâche.
    Code:
    /**************************************************************************
                        méthodes
    **************************************************************************/
     
    void MainWindow::keyPressEvent(QKeyEvent *ev)
    {
     
            if (ev->key() == Qt::Key_Z)
             {
                serial.write(trame_Av);  // J'envoie la trame au port serie
                qDebug()<<"Go";
                //(new QTimer())->start(500);
             }
    }
     
    void MainWindow::keyReleaseEvent(QKeyEvent *ev)
    {
        if(ev->isAutoRepeat())
        {
            return;
        }
        else
        {
            serial.write(trame_St); // J'envoie la trame au port serie
            qDebug()<<"Stop";
        }
    }
    Dans les faits ce fonctionne ! Ce qui est une bonne chose .
    Oui mais voila .
    1/ Je n'arrive pas a modifier le temps de l'autorepeat ?
    2/ Alors de l'appui sur une touche clavier, il se passe un petit laps de temps, entre le premier appui, et les répétitions. Ce qui est gênant pour piloter un robot roulant. Car en fait les moteurs reçoivent une impulsion, puis s’arrête brièvement et reparte ce coup ci sans interruption.

    Je ne sais pas si le 2/ ou pourra l'éviter ! par contre pour le 1/ je pensais peut etre mettre un Qtimer pour effectuer une pause ? mais sa fonctionne pas. Je suppose que le repeat n'en tiens pas compte . il faudrait que j'essaye en gérant la répétition moi même ?

    Avez vous des idées a me proposer pour arriver à mes fins ! et que mon fils puisse enfin faire avancer ce robot avec le clavier ou la souris ! sinon je vous l'envoie mon fils ça vous apprendra !

    Merci à vous

    -----
    C'est en faisant des erreurs; que l'on apprend le mieux !!

  2. #2
    Chanur

    Re : Qt en C++, appui sur une touche du clavier ?

    Bonjour,

    Moi, dans ce genre de cas, j'utilise un thread séparé pour les traitements dont j'ai besoin. Ça permet d'être libre et a en plus l'avantage d'éviter de bloquer le thread du gestionnaire d'évènements de Qt.
    Les méthodes keyPressEvent et keyReleaseEvent se contenteraient de mettre à true et à false un flag, et ton thread bouclerait tant que le flag est à true.

    Voir la classe QThread : ici ou , suivant ta version de Qt.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  3. #3
    PHIGE

    Re : Qt en C++, appui sur une touche du clavier ?

    Bonjour,

    Le thread est une solution mais seul, il balancera des répétitions très rapidement avec un rythme non contrôlé. En complément ou à la place, il est possible d'utiliser un Timer avec un temps de répétition préfixé qui est activé (enabled) lors du "press" et désactivé lors du "release" (en fait on reproduit l'auto repeat en contrôlant sa fréquence et sa latence).

    Sous Windows, il faut faire attention au fait qu'il peut y avoir plus d'une descente de touche pour une seule remontée à cause de l'autorepeat (doc MS :Because of the autorepeat feature, more than one WM_KEYDOWN message may be posted before a WM_KEYUP message is posted. The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition).

    Salutations

    Salutations

Discussions similaires

  1. [VB] Simuler l'appui d'une touche d'un gamepad !
    Par XDamienX007 dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 17/06/2014, 15h07
  2. [ARDUINO ∞] Simuler l'appui d'une touche de téléphone fixe.
    Par Linke741 dans le forum Électronique
    Réponses: 6
    Dernier message: 18/06/2013, 04h40
  3. clavier 16 touche
    Par MIRO klose dans le forum Électronique
    Réponses: 7
    Dernier message: 11/05/2010, 20h24
  4. Touche clavier
    Par stevenhides dans le forum Matériel - Hardware
    Réponses: 4
    Dernier message: 08/11/2008, 10h03
  5. Simulation d'appui sur une touche
    Par francescopaolo dans le forum Électronique
    Réponses: 1
    Dernier message: 05/09/2008, 14h56