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

Caml Discussion :

Question Labltk et Ocaml


Sujet :

Caml

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Décembre 2008
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Question Labltk et Ocaml
    Bonjour,

    J'essaie d'apprendre à utiliser Labltk sous Ocaml.
    Je souhaite faire une petite calculette avec une interface graphique.
    Cependant j'ai quelque problème sur la partie qui doit afficher le nombre qu'on entre.

    Voilà mon code :
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    open Tk;;
     
    let concat s t = (*Concatène 2 string : string -> sting -> string *)
      let i = (String.length s) and j = (String.length t) in
        if i = 0 then t
        else 
          if j = 0 then s
          else
    	let u = String.make (i + j) 'a' in
    	  for k = 0 to (i - 1)
    	  do u.[k] <- s.[k] done;
    	  for k = i to (i + j - 1)
    	  do u.[k] <- t.[k - i] done;
    	  u;;
     
    let affiche k res () = (* Affiche le string "k" dans le frame "res" *)
      Label.configure res ~text:k;;
     
    let out = ref "";; (* Initialise la sortie à la chaîne vide "" *)
     
    let init_win () =
      let root = Tk.openTk () in       (* Frame principale *)
     
      let frame_out = Frame.create root in (* Frame de sortie *)
      let output = Label.create frame_out ~height:3 ~relief:`Sunken in    (* La sortie *)
     
      let frame_0 = Frame.create root in (* Frame pour les bouttons *)
      let btt_0 = Button.create frame_0 ~width:5 ~text:"0" 
        ~command:( out := (concat "0" !out); affiche !out output) in (* Button 0, rajoute "0" sur la sortie et affiche la sortie *)
      let btt_1 = Button.create frame_0 ~width:5 ~text:"1"
        ~command:( out := (concat "1" !out); affiche !out output) in (* Button 1, rajoute "1" sur la sortie et affiche la sortie *)
     
        pack [frame_out;frame_0] ~side:`Top ~expand:true ~fill:`X ;
        pack [output] ~side:`Left ~expand:true ~fill:`X ;
        pack [btt_0;btt_1] ~side:`Left ~expand:true ~fill:`X ;
     
        mainLoop ()
    ;;
     
    init_win();;
    Mais lorsque je lance le programme, si je clique sur le button 0, il m'affiche bien 0, mais je clique une seconde fois, ça ne fait de plus.
    Je soupçonne l'initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    let out = ref "";;
    d'être à l'origine de ça.
    Je suppose que la fonctionne mainLoop() relance le programme en entier, je me trompe?
    J'ai donc fait une seconde version, où au lieu de mettre la valeur de sortie dans un vecteur, je le met dans un fichier externe. Et la place de l'initialisation, j'ouvre en lecture les données du fichier externe. Donc la boucle de la fonction mainLoop(), n'efface plus la sortie. Mais je me retrouve avec exactement le même problème, quand j'appuie plusieurs fois sur 0, ça ne fait rien.

    Mais ce que je trouve le plus étrange c'est que si je clique sur le button 1, il m'affiche toujours 10, mais lorsque je n'ai encore jamais clique sur le button 0.

    Pouvez-vous, m'éclairer sur mon petit problème?
    Merci d'avance.

  2. #2
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par xjingyu Voir le message
    Voilà mon code :
    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
     
    open Tk;;
     
    let concat s t = (*Concatène 2 string : string -> sting -> string *)
      let i = (String.length s) and j = (String.length t) in
        if i = 0 then t
        else 
          if j = 0 then s
          else
    	let u = String.make (i + j) 'a' in
    	  for k = 0 to (i - 1)
    	  do u.[k] <- s.[k] done;
    	  for k = i to (i + j - 1)
    	  do u.[k] <- t.[k - i] done;
    	  u;;
    Je me permets de te signaler que la fonction ^ de OCaml fait pareil, mais en mieux

    Citation Envoyé par xjingyu Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    let affiche k res () = (* Affiche le string "k" dans le frame "res" *)
      Label.configure res ~text:k;;
     .
     .
     .
      let btt_0 = Button.create frame_0 ~width:5 ~text:"0" 
        ~command:( out := (concat "0" !out); affiche !out output) in (* Button 0, rajoute "0" sur la sortie et affiche la sortie *)
    Le problème vient de l'argument command. Ca doit être une fonction de type unit -> unit (j'imagines, je n'ai pas regardé la doc). Le problème ici est que lorsque tu construit le bouton, tu exécutes le bloc out := (concat "0" !out); affiche !out output qui modifies out puis retourne la fonction d'affichage. Alors que ce que tu voudrais, c'est que la modification se fasse lorsque l'on appuie sur le bouton. Il faut donc le mettre dans le corps d'une fonction, avec quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      let btt_0 = Button.create frame_0 ~width:5 ~text:"0" 
        ~command:( fun () -> out := (concat "0" !out); affiche !out output ()) in ...
    Je ne sais pas si je suis très clair, mais il est important que tu comprennes bien ton erreur ! Le code que tu as mis après ~command: n'est pas le corps d'une fonction mais une expression qui est évaluée une seule fois, lors de la création du bouton.

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Décembre 2008
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci, d'avoir répondu aussi vite.

    Effectivement pour la concaténation de string, la fonction ^ est plus simple (je l'avais complètement oublié celle là ).

    En ce qui concerne la fonction commande elle bien du type unit -> unit, du coup la fait de mettre fun () -> ... ne marche plus, puisque ça devient du type unit tout court.

    Par contre, le fait que la commande s'éxécute lors de la création du boutton, je ne sais pas trop comment ça se passe. Par exemple je viens de rajouter un bouton 2, et dans ce cas, si j'appuie sur 0, il m'affiche 0, si j'appuie sur 1 et m'affiche 10, et si j'appuie sur 2 il m'affiche 210. C'est comme si le fait d'appuie sur un bouton lançait toutes les commandes des boutons définis avec celui-ci et pas ceux d'après. Je trouve ça assez étrange...

  4. #4
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par xjingyu Voir le message
    En ce qui concerne la fonction commande elle bien du type unit -> unit, du coup la fait de mettre fun () -> ... ne marche plus, puisque ça devient du type unit tout court.
    Pardon ?? Comment quelque chose de la forme fun () -> ... peut être de type unit ? C'est forcément de type unit -> ...


    Citation Envoyé par xjingyu Voir le message
    Par contre, le fait que la commande s'éxécute lors de la création du boutton, je ne sais pas trop comment ça se passe.
    Si tu as une fonction f qui attends un argument entier, si tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f (print_string "coucou"; 3 + 2)
    Ca va imprimer une seule fois coucou, calculer 5, puis appeler f. Bah là c'est pareil Sauf que dans ton cas, ce que tu retournes est une fonction. Mais ce qu'il y a avant n'est exécuté qu'une seule fois.

Discussions similaires

  1. camlimage + questions ocaml
    Par yardras dans le forum Caml
    Réponses: 1
    Dernier message: 02/01/2011, 21h00
  2. Questions débutant oCaml
    Par Tony_T dans le forum Caml
    Réponses: 4
    Dernier message: 14/10/2010, 15h21
  3. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11
  4. Question de faisabilité
    Par lisarasu dans le forum CORBA
    Réponses: 3
    Dernier message: 14/05/2002, 11h26
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 29/04/2002, 23h18

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