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 :

problème d'affichage de window avec lablgtk2


Sujet :

Caml

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut problème d'affichage de window avec lablgtk2
    slt tt le monde,
    Mon window principal contient des boutons qui ont pour rôle l'affichage d'autres windows.
    Mon problème consiste à:
    la première fois qd je clique sur le bouton le window désiré s'affiche sans problème ainsi que ts les widgets packés dedans
    mais après avoir fermer ce window; un nouveau clic sur le dit bouton, m'affiche juste un window vide sans les widgets.
    comment puis-je remedier à ça?

    (j'espère que j'arrive à vous faire comprendre mon pb)

  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 problème d'affichage de window avec lablgtk2
    Bonjour !

    Citation Envoyé par amiroushka
    la première fois qd je clique sur le bouton le window désiré s'affiche sans problème ainsi que ts les widgets packés dedans
    mais après avoir fermer ce window; un nouveau clic sur le dit bouton, m'affiche juste un window vide sans les widgets.
    comment puis-je remedier à ça?
    Lorsque tu fermes la sous-fenêtre, les widgets qu'elle contient sont détruits par GTK+ en raison de son mode de gestion de la mémoire à base de comptage de références. Pour résoudre le problème, il faut intercepter la fermeture de la sous-fenêtre pour la masquer et non la fermer. Voici un exemple ci-dessous :

    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
    let _ = GMain.init ()
    
    (* Fenêtre principale de l'application. *)
    let window = 
      let wnd = GWindow.window ~width:200 ~height:200 () in
      wnd#connect#destroy GMain.quit;
      wnd 
    
    (* Sous-fenêtre à afficher/masquer. *)
    let sub_window =
      let wnd = GWindow.window ~width:200 ~height:200 () in
      (* La ligne ci-dessous est cruciale. Si on l'efface, on retrouve le
       * comportement anormal que tu évoques dans ton message. *)
      wnd#event#connect#delete (fun _ -> wnd#misc#hide (); true);
      (* Ne doit jamais être affiché, sauf si tu supprimes la ligne ci-dessus. *)
      wnd#connect#destroy (fun () -> print_endline "Subwindow has been destroyed");
      let btn = GButton.button ~label:"Hide me" ~packing:wnd#add () in
      btn#connect#clicked wnd#misc#hide;
      wnd
    
    (* Le bouton d'affichage de la sous-fenêtre. *)
    let btn = 
      let btn = GButton.button 
        ~label:"Display subwindow" 
        ~packing:window#add () in
      btn#connect#clicked sub_window#show;
      btn
    
    let _ =
      window#show ();
      GMain.main ()
    Dans le code ci-dessus, l'événement delete est intercepté et permet de masquer la sous-fenêtre (#misc#hide ()). On renvoie ensuite true pour indiquer que l'on a fait le travail nous-mêmes. On évite ainsi la propagation de l'événement et le déclenchement de destroy.

    Test : ocamlopt -w s -I +lablgtk2 lablgtk.cmxa test.ml -o test && ./test

    Cordialement,
    Cacophrène

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut
    C'est parfait comme solution.
    Sauf que je veux qu'à chaque clic sur le bouton j'aurais mon window avec les widgets réinitialisés, par exp les zones de textes vides de nouveau, etc.
    est-il possible?

  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
    Salut !

    Citation Envoyé par amiroushka
    je veux qu'à chaque clic sur le bouton j'aurais mon window avec les widgets réinitialisés, par exp les zones de textes vides de nouveau
    C'est possible, et on peut le faire de deux façons au moins :

    • Avec view#buffer#set_text et une chaîne vide.
    • Avec view#buffer#delete et les GText.iter de début et de fin.

    Voici un code en guise d'exemple (les parties les plus importantes sont écrites en vert car le code lui-même est un peu long) :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    let _ = GMain.init ()
    
    (* Un texte fictif pour remplir les GText.view. *)
    let dots =
      let buf = Buffer.create 16 in 
      let str = String.make 80 'A' ^ "\n" in
      for i = 1 to 10 do Buffer.add_string buf str done;
      Buffer.contents buf
    
    (* La fenêtre principale. *)
    let window = 
      let wnd = GWindow.window 
        ~resizable:false 
        ~position:`CENTER () in
      wnd#connect#destroy GMain.quit;
      wnd
    
    let container = GPack.vbox
      ~spacing:10 
      ~border_width:10 
      ~packing:window#add ()
    
    (* Une fonction pour créer un GText.view avec des barres de défilement.
     * Le buffer du GText.view est initialisé avec le texte précédent. *)
    let make_view ~packing =
      let scroll = GBin.scrolled_window
        ~hpolicy:`ALWAYS
        ~vpolicy:`ALWAYS
        ~packing () in
      let view = GText.view ~wrap_mode:`CHAR ~packing:scroll#add () in
      view#buffer#set_text dots;
      view
    
    (* Une liste de 16 GText.view. *)
    let views =
      let table = GPack.table 
        ~rows:4 
        ~columns:4 
        ~row_spacings:10
        ~col_spacings:10
        ~homogeneous:true
        ~packing:container#add () in
      let rec loop acc = function
        | (4, _) -> acc
        | (i, 4) -> loop acc (i + 1, 0)
        | (i ,j) -> let packing = table#attach ~left:i ~top:j in
          loop (make_view ~packing :: acc) (i, j + 1)
      in loop [] (0, 0)
    
    (* La fonction qui permet d'effacer le contenu des buffers.
     * On peut aussi utiliser view#buffer#set_text "". *)
    let reset_buffers () =
      List.iter (fun view ->
        view#buffer#delete 
          ~start:view#buffer#start_iter
          ~stop:view#buffer#end_iter
      ) views
    
    (* Le bouton d'effacement. *)
    let clear_button =
      let btn = GButton.button 
        ~label:"Effacer" 
        ~packing:(container#pack ~expand:false) () in
      btn#connect#clicked reset_buffers;
      btn
    
    let _ = 
      window#show (); 
      GMain.main ()
    Pour tester : ocaml -w s -I +lablgtk2 lablgtk.cma test.ml

    Aperçu du code ici : http://www.box.net/shared/9yv18h53k9

    Cordialement,
    Cacophrène

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut
    En fait c'est presque la même chose que j'ai faite mais ça ne marche pas.
    Voila 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
     
    let register_multiple f = List.map (fun callback -> (f ~callback))
     
    let efface_entry_text widget ()=
      widget#set_text ""
     
    let efface_view_text widget ()=
       widget#buffer#set_text ""
     
    let bouton_ajout=
      let button=GButton.button
        ~label:"Add frame"
        ~packing:vbox_f2#add() in register_multiple button#connect#clicked [efface_entry_text entry1;efface_view_text view1; window2#show];
      button
    sachant que entry1 et view1 sont dans window2 alors que le bouton_ajout est dans un autre window.
    Ce dernier bouton a pour rôle de réinitialiser les champs de text et au même temps d'afficher le window2. je me suis dit pt être c pour ça que ça ne marche pas.

  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
    Re !

    Citation Envoyé par amiroushka
    sachant que entry1 et view1 sont dans window2 alors que le bouton_ajout est dans un autre window. Ce dernier bouton a pour rôle de réinitialiser les champs de text et au même temps d'afficher le window2. je me suis dit pt être c pour ça que ça ne marche pas.
    Bizarre (je n'arrive pas à reproduire ce comportement, même avec deux fenêtres séparées)... est-ce que certains bouts de code sont susceptibles de modifier le contenu de entry1 et view1 ?

    Cordialement,
    Cacophrène

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut
    je ne suis pas certaine de bien vous comprendre mais je n'ai aucun autre bout de code pour modifier le contenu de view1 et entry1.

    en fait j'ai essayé avec un autre bouton qui ne fait que supprimer le contenu de view1 et entry1 (le bouton est logé dans un autre window) et ça a marché.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut
    ah voila ça a marché.
    le problème est dû à l'ordre d'invocation des événements: il faut afficher le window après procéder à la suppression du contenu des zones de texte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [window2#show;efface_entry_text entry1;efface_view_text view1]

  9. #9
    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
    Salut !

    Citation Envoyé par amiroushka
    le problème est dû à l'ordre d'invocation des événements: il faut afficher le window après procéder à la suppression du contenu des zones de texte
    Tant mieux si ça marche , mais ça me semble quand même assez confus. Sous GTK les callback sont appelés dans l'ordre où ils ont été enregistrés. Or la liste qui commence par window2#show enregistre en premier l'affichage de la fenêtre (aucun problème lié à l'évaluation de droite à gauche en OCaml car List.map est bien codée). La fenêtre window2 est donc bel et bien affichée avant que le contenu de entry1 et view1 ne soit modifié. Je rappelle d'autre part que je n'ai pas eu ce problème de texte non effacé avec la liste qui se termine par window2#show. Bref, j'ai l'impression que ça vient d'autre chose (mais je suis bien incapable de dire précisément ce qui est en cause).

    Est-ce que vous compilez votre projet avec ocamlbuild ? Si c'est le cas, attention : il arrive quelquefois que des fichiers modifiés ne soient pas recompilés. En cas de doute, ne pas hésiter à nettoyer (ocamlbuild -clean) avant de recompiler.

    Évidemment, cela perd un peu de son intérêt dès lors que la solution est trouvée. Mais quand même, si c'est reproductible, c'est déroutant !

    Cordialement,
    Cacophrène

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 44
    Points : 23
    Points
    23
    Par défaut
    non je compile mon projet avec ocamlc

Discussions similaires

  1. Problème d'affichage sur Windows avec Dev-C++
    Par Cognote dans le forum Débuter
    Réponses: 2
    Dernier message: 29/07/2008, 09h04
  2. problème d'affichage d'image avec mozilla
    Par lyon31 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 16/03/2006, 16h27
  3. Affichage de windows avec propriété StayonTop
    Par Graffito dans le forum Linux
    Réponses: 2
    Dernier message: 27/01/2006, 09h17
  4. [Mail] Problème d'affichage d'HEADERS avec mail();
    Par JeanMi66 dans le forum Langage
    Réponses: 3
    Dernier message: 17/01/2006, 06h46
  5. Problème d'affichage de données avec crystal report
    Par napegadie dans le forum VB 6 et antérieur
    Réponses: 19
    Dernier message: 07/12/2005, 15h45

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