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

GTK+ avec C & C++ Discussion :

Erreur Gtk-CRITICAL dans une fenêtre secondaire


Sujet :

GTK+ avec C & C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut Erreur Gtk-CRITICAL dans une fenêtre secondaire
    Bonjour,

    Je viens poster un message ici car j'ai un problème avec le logiciel que je suis en train de modifier, un problème au niveau de GTK.

    Je vous explique donc mon problème :

    J'ai, pour commencer, une fenêtre principale, dans laquelle il y a un menu. Via ce menu, il y a possibilité de lancer une autre fenêtre pour gérer des paramètres!
    Dans cette fenêtre de paramètres, plusieurs choix sont disponibles, qui sont inutiles de préciser, et un bouton en bas est cliquable à tout moment, le bouton "Fermer", qui va cacher la fenêtre et enregistrer les nouveaux paramètres. Voici le code de ce bouton :
    WConfig.hbuttonbox = gtk_hbutton_box_new ();
    gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_END);
    gtk_container_add (GTK_CONTAINER (WConfig.vbox), WConfig.hbuttonbox);
    WConfig.buttonfermer = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
    gtk_container_add (GTK_CONTAINER (WConfig.hbuttonbox), WConfig.buttonfermer);
    g_signal_connect ((gpointer) WConfig.buttonfermer, "clicked",
    G_CALLBACK (buttonFermerConfig_clicked),
    NULL);

    Après, lorsque je relance la fenêtre de paramètres, tout fonctionne nickel.
    Si, au lieu de cliquer sur le bouton "Fermer", je clique sur la croix en haut à droite, la fenêtre ce cache et les paramètres sont enregistrés. Voici le code de ce boutton :
    WConfig.wconfig = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position (GTK_WINDOW(WConfig.wconfig),GTK_WIN_POS_CENTER);
    gtk_window_set_modal(GTK_WINDOW(WConfig.wconfig), TRUE);
    WConfig.vbox = gtk_vbox_new (FALSE, 10);
    gtk_container_add (GTK_CONTAINER (WConfig.wconfig), WConfig.vbox);
    g_signal_connect(WConfig.wconfig, "destroy", G_CALLBACK(buttonFermerConfig_clicked), NULL);

    Le problème étant que lorsque je relance cette fenêtre de paramètres, une erreur surviens, lié aux combos qui sont présent dans la fenêtre :

    (prog:12879): Gtk-CRITICAL **: gtk_widget_show_all: assertion `GTK_IS_WIDGET (widget)' failed

    (prog:12879): GLib-GObject-WARNING **: invalid uninstantiatable type `(null)' in cast to `GtkEntry'

    (prog:12879): Gtk-CRITICAL **: gtk_entry_set_text: assertion `GTK_IS_ENTRY (entry)' failed

    (prog:12879): GLib-GObject-WARNING **: invalid uninstantiatable type `(null)' in cast to `GtkComboBox'

    (prog:12879): Gtk-CRITICAL **: gtk_combo_box_get_model: assertion `GTK_IS_COMBO_BOX (combo_box)' failed

    (prog:12879): Gtk-CRITICAL **: gtk_tree_model_get_iter_first: assertion `GTK_IS_TREE_MODEL (tree_model)' failed

    (et bien d'autre mais identique, qui sont reliés à d'autres combos).

    J'ai donc était voir dans la FAQ de GTK+ la différence entre "cliqued" et "delete-event", ce qui m'a permis de mettre, dans ma fonction callback, la fonction :
    gtk_widget_hide_on_delete (WConfig.wconfig);
    à la place de la fonction :
    gtk_widget_hide (WConfig.wconfig);

    Résultat : aucun changement, le bug persiste.
    Je pense que lorsque je clique sur la croix, cela ferme la fenêtre, et je suis obligé de réinitialiser tout les combo et le reste pour pouvoir réafficher ma fenêtre correctement, mais je n'en suis pas sur du tout, n'étant pas un pro en GTK+ (loin de là ) ...

    Je vous demande donc de m'aider à comprendre ce problème et ainsi trouver une solution, car cela est plutôt embétant(surtout avec moi qui clique souvent sur la croix et non sur le bouton Fermer ... -_-)


    Merci d'avance pour vos réponses!

    Ridbark

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Ridbark Voir le message
    ...g_signal_connect ((gpointer) WConfig.buttonfermer, "clicked",
    G_CALLBACK (buttonFermerConfig_clicked),
    NULL);

    ...
    g_signal_connect(WConfig.wconfig, "destroy", G_CALLBACK(buttonFermerConfig_clicked), NULL);
    Ridbark
    Sans trop regarder plus en détail tu appelles deux fois le même callback avec des signaux différents. Jusque là rien d'impossible. Mais le signal "clicked" demande un prototype de callback comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void                user_function                      (GtkButton *button,
                                                            gpointer   user_data)
    et le signal "destroy" un callback de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void                user_function                      (GtkObject *object,
                                                            gpointer   user_data)
    Même si ces deux prototypes se ressemblent utilises-tu le premier argument? Un conflit peut déjà apparaître là.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Voici la fonction que j'utilise :

    void buttonFermerConfig_clicked (GtkButton *button, gpointer user_data);

    Faut-il donc que j'en fasse une autre pour le signal "destroy"?

    Et non, je n'utilise pas la variable *button.

    Ridbark

  4. #4
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Non pas forcément puisque tu n'utilises aucun des pointeurs transmis. Par contre l'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (prog:12879): Gtk-CRITICAL **: gtk_widget_show_all: assertion `GTK_IS_WIDGET (widget)' failed
    me fait dire que la fenêtre que tu tentes d'afficher n'existe pas (ou plus).

    Es-tu sûr de ne pas avoir laissé traîné un gtk_widget_destroy(); quelque part dans ton code? Ou bien tu perds le pointeur de la fenêtre dans le processus.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Je viens de vérifier correctement toutes les fonctions qui découles de ma fonction callback et non, aucun gtk_widget_destroy() en vu! Enfin, pas pour la fenêtre de paramètres! (Car lorsque je ferme la fenêtre de paramètres, un barre s'affiche pour dire que l'ordinateur est en train de sauvegarder les nouveaux paramètres et de les mettrent en application, donc une fenêtre qui est détruite à la fin car elle ne contient aucune donnée utile au programme, c'est juste pour faire patienter ...).

    Et comment pourrais-je perdre le pointeur de la fenêtre dans le processus?
    De plus, le bouton "Fermer" et la croix exécute la même fonction callback, c'est ça que je ne comprends pas, ils devraient faire la même chose mais ça bug avec la croix et pas avec le bouton "Fermer" ... serait-il possible que le fait de ne pas renvoyer TRUE a la fin de ma fonction callback fasse que le signal "delete-event" ferme la fenêtre au lieu de simplement la cacher comme je lui demande?


    Ridbark

  6. #6
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    La croix envoie le signal "delete-event" mais aussi "destroy". Donc effectivement si tu n’interceptes pas les deux signaux c'est sûrement là que ca coince.
    Ta solution de renvoyer TRUE peut fonctionner à partir du moment où l'ordre d'appel des signaux est le bon. En d'autres termes si ton callback est appelé en premier. Dans le cas contraire affecte un callback aux deux signaux et renvoie TRUE. Ca réglera définitivement le problème.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Si j'ai bien compris, moi je traite le signal delete-event, mais le signal destroy est automatiquement traité? Donc si je fait :

    g_signal_connect(WConfig.wconfig, "delete-event", G_CALLBACK(buttonCroixConfig_clicked), NULL);
    g_signal_connect(WConfig.wconfig, "destroy", G_CALLBACK(buttonFermerConfig_clicked), NULL);

    Avec la fonction buttonCroixConfig_clicked qui renverrais juste TRUE et la fonction buttonFermerConfig_clicked qui enregistrerais les paramètres et cacherais simplement la fenêtre?(ou bien le contraitre au niveau des fonction callback, qui appelle qui)

    Si c'est pas ce que tu as voulu dire, et bien je n'ai pas bien compris alors ... :S


    Ridbark

  8. #8
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Oui c'est à peu prés ca. Mais attention au signal "delete-event". Le prototype du callback pour ce signal est de la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    gboolean            user_function                      (GtkWidget *widget,
                                                            GdkEvent  *event,
                                                            gpointer   user_data)
    Donc tu ne pourras pas l'attacher à la même fonction.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Oui mais justement, si je le rattache à une fonction qui ne renverra que TRUE et que j'attache plutot le signal "destroy" à la fonction qui est aussi attaché à mon bouton "Fermer", du coup, l'enregistrement ce fera quand même et la fenêtre sera cachée! Ou bien faut-il que je fasse l'enregistrement dans la fonction callback qu'appellera le signal "delete-event"?


    Ridbark

  10. #10
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Je reviens sur ce que je t'ai dit. Je viens de faire un petit programme test. Seul le signal "delete-event" est appelé. Il te suffit de renvoyé TRUE à la fin du callback appelé.

    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 <stdlib.h>
    #include <gtk/gtk.h>
     
    gboolean callback_delete_event (GtkWidget *widget, GdkEvent  *event, gpointer   user_data)
    {
      g_print("appel de la fonction callback_delete_event\n");
      return TRUE;
    }
     
    int main(int argc, char **argv)
    {
      GtkWidget *pWindow;
     
      gtk_init(&argc, &argv);
     
      pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     
      gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
      g_signal_connect(G_OBJECT(pWindow), "delete-event", G_CALLBACK(callback_delete_event), NULL);
     
     
      gtk_widget_show_all(pWindow);
      gtk_main();
      return EXIT_SUCCESS;
    }

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Superviseur de Hotline
    Inscrit en
    Mai 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Superviseur de Hotline
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2011
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Ah, cool!
    Donc j'appelle une fonction callback exprès pour le signal "delete-event" et dans cette fonction, j'appelle ma fonction callback pour enregistrer les paramètres, puis je renvois TRUE, d'accord, et bien j'essayerais donc ça dés demain matin!

    Merci beaucoup pour ton aide!

    Ridbark

    EDIT : Je viens tout juste de mettre en application ce que tu m'as proposé hier soir, et ça marche super bien, encore merci beaucoup!

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/08/2014, 17h42
  2. Zone de Dessin dans une fenêtre [GTK 3 & Cairo]
    Par Twice22 dans le forum GTK+ avec C & C++
    Réponses: 14
    Dernier message: 04/05/2013, 10h41
  3. [GTK+] Signal lors de la fermeture d'une fenêtre secondaire
    Par Skarsnick dans le forum GTK+ avec C & C++
    Réponses: 7
    Dernier message: 15/02/2010, 08h53
  4. Réponses: 2
    Dernier message: 09/02/2008, 01h23
  5. Afficher un message d'erreur dans une fenêtre popup
    Par Quickeno dans le forum Langage
    Réponses: 7
    Dernier message: 08/10/2006, 01h56

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