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

Langage C++ Discussion :

Entrée clavier qui ne bloque pas l'exécution.


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Entrée clavier qui ne bloque pas l'exécution.
    Bonjour à tous,

    Je développe en ce moment une application multi-plateformes en C++ basée sur des évènements et j'ai besoin de programmer une interface utilisateur.

    J'ai deux contraintes :
    - je dois développer ça très vite
    - l'exécution du programme ne doit pas se bloquer pendant que l'utilisateur tape au clavier (le programme reçoit des évènements de diverses sources, pas que de l'utilisateur).

    L'interface doit être très simple : en gros à chaque fois que l'utilisateur appuie sur entrée ça envoie ce qu'il vient de taper à un gestionnaire d'évènements.


    J'aurais aimé savoir s'il existe un moyen simple et portable de faire ceci.
    L'idéal aurait été de pouvoir faire ça avec l'entrée standard ou quelque chose s'en rapprochant (en permettant à l'utilisateur de mettre des trucs dans un buffer pendant que le programme s'exécute et en vérifiant périodiquement le contenu du buffer, ça ne me paraît pas absurde).

    Merci d'avance.




    PS : C'est la première fois que je programme une véritable application en C++ (j'ai fait beaucoup de problèmes de type ACM en C++ et je viens de Python et Ocaml).
    Je travaille essentiellement avec Code::blocks ou à la main sous linux.
    J'utilise GCC (g++) pour compiler et mingw sous windows.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    De portable en C, il y a pdcurses. En C++, je ne sais pas s'il y a autre chose pour les applications console.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    A mon avis, ce que vous espérez est la situation de base, et en fait très difficile (voire impossible) à contourner.
    En effet la question a été posée de faire réagir le programme à la frappe d'une touche, sans appuyer sur "Entrée". On n'y est pas arrivé.
    Les OS actuels (contrairement au DOS) sont basés sur la réaction aux évènements. Tant que l'opérateur n'a pas appuyé sur Entrée, il peut faire tout ce qu'il veut, l'ordinateur vit sa vie de son côté et le programme regarde de temps en temps si la touche Entrée a été appuyée. Pour le forcer à regarder à un moment donné, il faut utiliser la fonction ProcessMessage().
    Cordialement.

    PS Naturellement, il ne faut pas que le programme contienne une fonction du type OnKeyDown(). Si c'est le cas, cette fonction doit être immédiatement suivie du test <Touche Entrée>

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    ^En fait, on y est arrivé depuis longtemps, seulement, pas en 100% portable (et donc, pas en C++ standard non plus).

    D'où la nécessité d'utiliser soit l'API système de la plate-forme, soit une bibliothèque dite "portable" comme pdcurses.

    Et il y a de grandes chances qu'un tel programme doive s'articuler autour d'une boucle d'attente active ou semi-active (faire du polling, quoi).

  5. #5
    Invité
    Invité(e)
    Par défaut
    Merci pour l'info.
    Cette question a fait l'objet d'un sujet et a été évoqué de nouveau dernièrement.
    Hors bibliothèque supplémentaire, peut-on avoir un bout de code. Merci d'avance.
    En C++, je ne sais pas s'il y a autre chose pour les applications console.
    Je ne comprend pas cette phrase de votre réponse précédente. dark_tangente parle de frappe au clavier et non pas d'application console.

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    Hors bibliothèque supplémentaire, peut-on avoir un bout de code. Merci d'avance.
    Pour quel OS?

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Tout d'abord, merci pour ces réponses.

    Pdcurses est une possibilité, je vais regarder de plus près.


    Citation Envoyé par Pierre Dolez Voir le message
    Bonjour,
    A mon avis, ce que vous espérez est la situation de base, et en fait très difficile (voire impossible) à contourner.
    En effet la question a été posée de faire réagir le programme à la frappe d'une touche, sans appuyer sur "Entrée". On n'y est pas arrivé.
    Les OS actuels (contrairement au DOS) sont basés sur la réaction aux évènements. Tant que l'opérateur n'a pas appuyé sur Entrée, il peut faire tout ce qu'il veut, l'ordinateur vit sa vie de son côté et le programme regarde de temps en temps si la touche Entrée a été appuyée. Pour le forcer à regarder à un moment donné, il faut utiliser la fonction ProcessMessage().
    Cordialement.

    PS Naturellement, il ne faut pas que le programme contienne une fonction du type OnKeyDown(). Si c'est le cas, cette fonction doit être immédiatement suivie du test <Touche Entrée>
    Et il y a de grandes chances qu'un tel programme doive s'articuler autour d'une boucle d'attente active ou semi-active (faire du polling, quoi).
    Peut-être qu'on s'est mal compris ici.

    Tout d'abord, arrêtez moi si je me trompe :
    lorsque j'écris quelque chose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::string bob;
    std::cin >> bob ;
    alors le programme se met en attente (active, passive, peu importe) et lorsque la touche ENTREE est pressée il évalue le contenu de cin et réagit en conséquence.

    Tout ce que je veux dans mon programme c'est l'empêcher de se mettre en attente et inspecter moi-même le contenu de cin de façon périodique à l'aide d'une boucle. La différence c'est que dans mon programme il peut y avoir d'autres évènements que l'appui sur la touche ENTREE (qui n'ont rien à voir avec la console). À chaque tour de boucle j'irais voir si l'utilisateur a appuyé sur ENTREE depuis la dernière fois et j'irais vérifier mes autres sources d'évènements. Mon programme sera aussi en attente, mais pas seulement d'un appui sur ENTREE.
    Le problème c'est qu'à moins qu'on écrive quelque chose comme "cin >>..." (ce qui provoque une attente) alors l'utilisateur ne peut pas écrire dans la console (du moins sous windows).

    Je ne veux pas que mon programme réagisse à la pression des touches ou ce genre de choses.


    J'espère que je suis un peu plus clair sur ce coup là


    PS : j'ai bien conscience que cin ne peut pas faire tout ce que j'évoque plus haut (ou alors si c'est le cas mon problème est résolu). J'ai pris cet exemple pour illustrer la façon dont je voyais les choses.

    PPS :
    Je ne comprend pas cette phrase de votre réponse précédente. dark_tangente parle de frappe au clavier et non pas d'application console.
    En fait je me fiche de réagir à la frappe de chaque touche.
    Je veux juste un moyen simple de récupérer du texte qui s'intègre bien dans ma boucle d'évènements. Passer par la console est probablement la solution la plus simple.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    Je ne comprend pas cette phrase de votre réponse précédente. dark_tangente parle de frappe au clavier et non pas d'application console.
    Le problème ne se présente que dans une application console: Dans une application GUI fenêtrée, le programme ne fait jamais* d'attente de touche bloquante.

    Cela signifie que s'il on peut faire une application GUI plutôt que console (au regard des autres contraintes), il ne faut pas se priver en effet. Et les bibliothèques GUI ne manquent pas: gtkmm, Qt, WxWidgets...

    *Sauf bizarrerie

  9. #9
    Invité
    Invité(e)
    Par défaut
    @Médinoc
    Ok 1 point pour vous.
    @Jean-Marc.Bourget.
    En fait ce problème de saisie sans appuyer su la touche Entrée ne m'intéresse pas personnellement, mais elle a fait l'objet de pas mal d'échanges, et si quelqu'un a un solution je suis sûr que cela intéressera celui qui la cherche.
    Moi, j'ai essayé de trouver sous Windows XP, il y a bien longtemps sous UNIX, mais comme je travaille avec un environnement graphique, en ce qui me concerne, je n'en ai pas besoin.

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    il y a bien longtemps sous UNIX
    La bonne méthode est (n)curses. Si on veut taper à un niveau plus bas, il suffit de chercher "unix terminal IO", les exemples abondent. Pour commencer dans la doc de la libc sous Linux, chapitre "17 Low-Level Terminal Interface".

  11. #11
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Sinon, juste mettre le cin dans un thread séparé, ça devrait suffire, non ?

  12. #12
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    Sinon, juste mettre le cin dans un thread séparé, ça devrait suffire, non ?
    non, ce qui est souhaité n'est pas ne pas bloquer l'application, mais de traiter immédiatement la saisie d'un caractère sans que l'utilisateur donne le faire suivre par la touche entrée. Par exemple lorsque vous utiliser more sous Linux/Unix vous passer à la page suivante simplement en tapant la touche espace, pas besoin de taper un espace suivit d'entrée ... ce qui montre bien que cela est possible sans IHM comme le signale Jean-Marc Bourguet (qui de toute façon ne dit jamais de bêtise )

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bonjour Bruno Pagès,
    Je suis bien d'accord, la frappe d'un caractère est lue par le système et enregistrée au fur et à mesure, mais les lectures clavier ne sont prises en compte par les fonctions de lecture qu'après validation par Entrée.
    L'exemple de more : more n'est pas une fonction, mais une commande.

    J'ai beaucoup réfléchi, testé ce problème et essayé toute sorte de chose, par exemple renommer stdin (j'oublie le terme exact cad 0>Clavier), simuler la frappe de la touche Entrée etc. je pense qu'il n'y a que les spécialistes en assembleur qui pourraient trouver une solution. Il devrait bien y en avoir sur ce forum.

  14. #14
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    Citation Envoyé par Pierre Dolez Voir le message
    more n'est pas une fonction, mais une commande.
    il a bien fallut l'implémentée, et vous pouvez être sure qu'elle est écrite en C

    Citation Envoyé par Pierre Dolez Voir le message
    je pense qu'il n'y a que les spécialistes en assembleur qui pourraient trouver une solution
    mais non, il suffit de trouver comment paramétrer la chose pour être en mode non bloqué comme déjà annoncé (exemple), je regarderai plus en détail plus tard

  15. #15
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @Pierre Dolez: Jean-Marc t'as donné une piste : section 17 de la doc libc, j'ai été voir (très vite), tu peus rajouter "Noncanonical Input" comme mots-clé et tu devrais avoir une solution viable.

  16. #16
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 534
    Points : 6 723
    Points
    6 723
    Par défaut
    l'exemple que j'avais cité donne de bonnes infos, sous Suse Linux le code suivant permet bien de lire des caractères au vol :
    Code : 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
    #include <termios.h>
    #include <unistd.h>
    #include <stdio.h>
     
    int main(int, char **)
    {
      struct termios t;
     
      // prend le paramétrage courant,  0 indique le flux d'entrée (stdin)
      tcgetattr(0, &t);
     
      // passe en mode non bloquant
      cfmakeraw(&t);
     
      // positionne le mode non bloquant pour le fluw d'entrée
      tcsetattr (0, TCSANOW, &t);
     
      // boucle sur la saisie de caractère et sur sur control-c
      int c;
     
      while ((c = getchar()) != 3) // 3 = control-c
        printf("%d\n", c);
     
      return 0;
    }

  17. #17
    Invité
    Invité(e)
    Par défaut
    Merci pour Dark_tangente.
    Mais, moi, je travaille sous Windows dans un environnement graphique.
    Et, je n'ai pas les header nécessaires.
    J'avais seulement essayé d'aider
    Bonne soirée.

  18. #18
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Je ne suis pas certain d'avoir bien compris parceque la question parceque le reste de la discussion pars dans une direction qui me semble bien overkill.

    Si j'ai bien compris, diverses utilisateurs envoient pouvoir entrer des "commandes" en texte qui seront traitées mais de manière asynchrones.

    Alors pourquoi ne pas utiliser une architecture client/server?

    Il y a 2 types de messages (au moins) :
    - celui qui contiens une commande
    - celui qui contient le résultat de la commande (peut être juste un message "done"/"fail")

    Une simple application qui gère les messages serait un serveur (qu'il soit lancé d'abord par l'utilisateur ou bien automatiquement lancé par le client).
    Une simple application qui ne fait que prendre les commandes pour l'envoyer au serveur serait le client.

    Avec un peu d'experience avec des libs de réseau, ça me semble faisable rapidement (mais c'est relatif au sens de ce mot ici).

Discussions similaires

  1. problème d'entrée clavier qui ne ressort pas
    Par minimorphee dans le forum Débuter avec Java
    Réponses: 11
    Dernier message: 23/03/2014, 19h19
  2. Temporisation qui ne bloque pas l'application
    Par Zorgloub dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 14/02/2008, 17h55
  3. alert() qui ne bloque pas le chargement de la page ?
    Par Cofondinde dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/08/2007, 11h31
  4. recvfrom qui ne bloque pas ?
    Par innosang dans le forum Réseau
    Réponses: 1
    Dernier message: 21/06/2007, 12h11
  5. Réponses: 8
    Dernier message: 25/11/2005, 19h38

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