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 :

[LablGTK] Affecter une fonction à un bouton d'une toolbar


Sujet :

Caml

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juillet 2011
    Messages : 61
    Points : 27
    Points
    27
    Par défaut [LablGTK] Affecter une fonction à un bouton d'une toolbar
    Bonsoir,

    Soit le bout de code suiva
    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
    nt :
     
    let toolbar = GButton.toolbar  
      ~orientation:`HORIZONTAL  
      ~style:`ICONS 
      ~packing:(box#pack ~expand:false) () 
     
    let data = [`B `NEW; `B `OPEN; `B `SAVE; `S; `B `CUT; `B `COPY; `B `PASTE; `S; 
     `T "Bascule"; `S; `M days ] 
     
    let _ = 
      let packing = toolbar#insert in 
      List.iter (function 
        | `S -> ignore (GButton.separator_tool_item ~packing ()) 
        | `B stock -> ignore (GButton.tool_button ~stock ~packing ()) 
        | `T label -> ignore (GButton.toggle_tool_button ~label ~packing ()) 
        | `M menu -> ignore (GButton.menu_tool_button ~label:"Foo" ~menu ~packing ()) 
        | _ -> () 
      ) data

    J'aimerai savoir comment afecter au 1er bouton de la liste data une fonction. Typiquement, j'ai fait une fonction pour ouvrir et afficher une image et je souhaite la connecter au 1er bouton de ma toolbar.

    Voila ce que j'ai essayé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (List.nth data 0)#connect#clicked (fun () -> print_endline "ok")
    Merci d'avance pour votre aide

  2. #2
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Ça ne marche pas parce que la liste data ne contient pas d'objets mais des valeurs comme `B `OPEN ! Deux possibilités :

    • Créer une liste data' en remplaçant ton List.iter par un List.map qui transforme une valeur de type `B `OPEN en un objet de type GButton.tool_item.
    • Utiliser quelque chose comme toolbar#get_nth_item.

    À titre personnel, pour la facilité d'utilisation, je préfère de loin la première solution ! Un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    type ('a, 'b, 'c) item = S | B of 'a | T of 'b | M of 'c
    
    let get_toolitems (toolbar : GButton.toolbar) items =
      let packing = toolbar#insert in
      List.map (function
        | S -> GButton.separator_tool_item ~packing (); S
        | B stock -> B (GButton.tool_button ~stock ~packing ())
        | T label -> T (GButton.toggle_tool_button ~label ~packing ())
        | M menu -> M (GButton.menu_tool_button ~menu ~packing ())
      ) items
    Cette fonction possède la signature suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    val get_toolitems :
      GButton.toolbar ->
      (GtkStock.id, string, < as_menu : Gtk.menu Gtk.obj; .. >) item list ->
      (GButton.tool_button, GButton.toggle_tool_button, GButton.menu_tool_button) item list
    Ensuite, tu peux définir les actions associées à chaque bouton de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let set_actions items funcs = 
      List.iter2 (function
        | B button -> (fun f -> ignore (button#connect#clicked ~callback:f))
        | T toggle -> (fun f -> ignore (toggle#connect#toggle ~callback:f))
        | _ -> ignore
      ) items funcs
    Cordialement,
    Cacophrène

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juillet 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juillet 2011
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Bonsoir Cacophrene et merci pour ta réponse.

    J'ai essayé de tout comprendre et je pense avoir saisi le truc.

    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
     
    let data = [ `S; `M other;`S ;`B `NEW; `B `OPEN; `B `SAVE; `S; `B `CUT; ]
     
    let get_toolitems (toolbar : GButton.toolbar) data =
      let packing = toolbar#insert in
      List.map (function
        | `S -> ignore (GButton.separator_tool_item ~packing ()) 
        | `B stock -> ignore (GButton.tool_button ~stock ~packing ()) 
        | `T label -> ignore (GButton.toggle_tool_button ~label ~packing ()) 
        | `M menu -> ignore (GButton.menu_tool_button ~label:"Foo" ~menu ~packing ()) 
        | _ -> () 
      ) data
     
     
     
    let set_actions data funcs = 
      List.iter2 (function
        | `B stock -> (fun f -> ignore (stock#connect#clicked ~callback:confirm))
        | `T label -> (fun f -> ignore (label#connect#toggle ~callback:f))
        | _ -> ignore
      ) data funcs
     
    let _ = 
      let packing = toolbar#insert in 
      List.iter (function 
        | `S -> ignore (GButton.separator_tool_item ~packing ()) 
        | `B stock -> ignore (GButton.tool_button ~stock ~packing ()) 
        | `T label -> ignore (GButton.toggle_tool_button ~label ~packing ()) 
        | `M menu -> ignore (GButton.menu_tool_button ~label:"Foo" ~menu ~packing ()) 
        | _ -> () 
      ) data
    Je me suis donc basé sur ce que tu as fait pour améliorer mon menu. Le truc c'est que sans ma derniere fonction, toute en bas, les boutons n'apparaissent pas. J'ai l'impression qu'il faut absolument le List.iter pour afficher les boutons sur mon interface. Est-ce normal ? J'ai dû rater quelque chose de relativement stupide

  4. #4
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    Effectivement, il y a deux choses qui ne vont pas. La première, tu dois enlever les ignore dans List.map car tu veux justement récupérer les objets et non les ignorer ! Attention, comme ils n'ont pas tous le même type, tu peux réutiliser `S, `B, `T et `M pour créer la liste d'objets. Je t'invite à bien considérer la différence entre List.iter et List.map :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    val ignore : 'a -> unit
    val iter : ('a -> unit) -> 'a list -> unit
    val map : ('a -> 'b) -> 'a list -> 'b list
    La deuxième chose qui ne va pas, il est vrai toute bête : ton code n'utilise pas la fonction get_toolitems ! Il faut écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    let _ = get_toolitems toolbar data
    Là ça devrait marcher.

    Cordialement,
    Cacophrène

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juillet 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juillet 2011
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Bonsoir,

    Il y a un petit truc que je n'ai pas saisi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let _ = get_toolitems toolbar data
    Doit-il être tout seul quelque part ? Ou dois-je l'utiliser dans une fonction avec le mot clé in ?

    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
    let get_toolitems (toolbar : GButton.toolbar) data =
      let packing = toolbar#insert in
      List.map (function
        | `S -> GButton.separator_tool_item ~packing () 
        | `B stock -> GButton.tool_button ~stock ~packing () 
        | `T label -> GButton.toggle_tool_button ~label ~packing () 
        | `M menu -> GButton.menu_tool_button ~label:"Foo" ~menu ~packing () 
        | _ -> () 
      ) data
     
     
     
    let set_actions data funcs = 
      List.iter2 (function
        | `B stock -> (fun f -> ignore (stock#connect#clicked ~callback:confirm))
        | `T label -> (fun f -> ignore (label#connect#toggle ~callback:f))
        | _ -> ignore
      ) data funcs
     
    let _ = 
      let packing = toolbar#insert in 
      List.iter (function 
        | `S -> ignore (GButton.separator_tool_item ~packing ()) 
        | `B stock -> ignore (GButton.tool_button ~stock ~packing ()) 
        | `T label -> ignore (GButton.toggle_tool_button ~label ~packing ()) 
        | `M menu -> ignore (GButton.menu_tool_button ~label:"Foo" ~menu ~packing ()) 
        | _ -> () 
      ) data

    Cordialement,
    polow

  6. #6
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    En OCaml, le filtrage est partout. L'expression let _ = foo doit être vue comme let x = foo; seulement, la valeur de x ne nous intéresse pas, d'où le wildcard _. Le code qui se trouve après cette déclaration (soit foo dans mon cas) est donc exécuté une et une seule fois, au moment où le code est évalué. Par exemple, dans un code qui utilise LablGTK, on trouve généralement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let _ =
      window#show ();
      GMain.main ()
    Dans ton cas, le code get_toolitems toolbar data permet de construire une partie de l'interface. Cette fonction te renvoie une liste d'objets dont tu vas avoir besoin pour y associer des actions, donc tu as effectivement besoin de la conserver. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    let data = [`T "foo"; `B `OPEN; ...]
    
    let _ =
      let widgets = get_toolitems toolbar data in
      set_actions widgets funcs;
      window#show ();
      GMain.main ()
    Encore une info : attention à ce que tu as écrit, ta fonction get_toolitems a toujours un problème, car les fonctions GButton.tool_button, GButton.menu_tool_button et GButton.toggle_tool_button ne renvoient pas des widgets du même type ! Regarde le code que je t'ai donné, tu dois réutiliser les constructeurs (ou les variants polymorphes puisque tu as l'air de les préférer) ! Avec OCaml, il est judicieux de raisonner en termes de types.

    Cordialement,
    Cacophrène

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juillet 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Juillet 2011
    Messages : 61
    Points : 27
    Points
    27
    Par défaut
    Sujet résolu, merci beaucoup Cacophrene

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

Discussions similaires

  1. Bouton avec une fonction ayant en argument une autre fonction
    Par Serratonique dans le forum Général Python
    Réponses: 8
    Dernier message: 28/02/2014, 18h53
  2. Passer une Fonction comme argument d'une fonction
    Par ch16089 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 27/02/2011, 17h58
  3. Réponses: 3
    Dernier message: 16/04/2009, 08h34
  4. [Langage] une fonction comme argument d'une fonction?
    Par Krishna dans le forum Langage
    Réponses: 9
    Dernier message: 15/10/2008, 20h31
  5. passage d'une fonction en parametre d'une fonction
    Par psylox dans le forum Langage
    Réponses: 5
    Dernier message: 06/10/2008, 16h40

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