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 :

Callback et g_signal_connect ne sont pas mes amies


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 14
    Par défaut Callback et g_signal_connect ne sont pas mes amies
    Bonsoir à tous,

    Je me suis interessé récemment à l'interface graphique GTK+ pour un projet de langage C que j'ai à faire (merci les études).
    Mon projet est de réaliser une calculatrice "graphique", je ne rentrerais pas plus dans les détails sauf si cela intéresse quelqu'un.


    J'ai suivi des tutos à droite et à gauche pour commencer l'ascension de ce géant.
    Malheureusement, dès le départ je bloque et c'est devenu décourageant.
    C'est pourquoi je viens solliciter un peu votre gentillesse (et vos connaissances) pour me sortir de là.

    Donc voici mon code :
    *Ma fonction executrice
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include "affiche.h"
     
    #define TAILLE 16
     
    int main(int argc, char **argv)
    {
     
    /*widget principal*/
    GtkWidget *Ma_Fenetre = NULL;
    /*widget important (conteneur)*/
    GtkWidget *Mon_Tableau = NULL;
    /*widgets actions (boutons ou zone de textes ...)*/
    GtkWidget *Mon_Bouton_Quitter = NULL;
    GtkWidget *Ma_Zone_Texte = NULL;
    GtkWidget *Mon_Bouton[TAILLE] = {NULL};
     
     
      /* Initialisation de GTK+ */
      gtk_init (&argc, &argv);
     
    /* Creation de la fenetre principale de notre application */
    Ma_Fenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);/*Création officielle de la fenetre xd*/
     
    gtk_window_set_default_size(GTK_WINDOW (Ma_Fenetre), 420, 380);
     
    gtk_window_set_title (GTK_WINDOW (Ma_Fenetre), "Calculatrice");
    gtk_window_set_position(GTK_WINDOW (Ma_Fenetre), GTK_WIN_POS_CENTER);
     
    g_signal_connect (G_OBJECT (Ma_Fenetre), "destroy", G_CALLBACK (gtk_main_quit), NULL); /*Lorsque l'utilisateur appuie sur la croix le programme est stoppé (il ne tourne plus)*/
     
     
    /* Creation du tableau et placement*/
    Mon_Tableau = gtk_table_new(7,4,TRUE);
    gtk_container_add(GTK_CONTAINER(Ma_Fenetre),GTK_WIDGET(Mon_Tableau));
     
     
    	/* Creation de la zone de texte */
     
    	Ma_Zone_Texte = gtk_text_view_new ();
     
    	gtk_table_attach_defaults (GTK_TABLE (Mon_Tableau), Ma_Zone_Texte, 0, 4, 0, 1);/*Gauche, Droite toujours + grand que gauche, Haut, Bas toujours + grand que haut*/
     
     
    	/*Creation du bouton Quitter*/
    	Mon_Bouton_Quitter = gtk_button_new_from_stock (GTK_STOCK_QUIT);
    	gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton_Quitter,2,3,6,7);
    	g_signal_connect (G_OBJECT (Mon_Bouton_Quitter), "clicked", G_CALLBACK (gtk_main_quit), NULL);/*Lorsque l'utilisateur appuie sur le bouton quitter le programme est stoppé (il ne tourne plus)*/
     
     
    		/* Creation des boutons standars de la calculatrice et placement*/
     
    /* C'est cette partie qui me pose probleme*/
     
    		Mon_Bouton[0] = gtk_button_new_with_label("0");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[0],0,1,6,7);
    		/*g_signal_connect (G_OBJECT (Mon_Bouton[0]), "clicked", G_CALLBACK (cb_affiche(Mon_Bouton[], Mon_Bouton[0])), Ma_Zone_Texte);*/
     
    		Mon_Bouton[1] = gtk_button_new_with_label("1");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[1],0,1,5,6);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[1]), "clicked", G_CALLBACK (cb_affiche(Mon_Bouton[], Mon_Bouton[1])), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[2] = gtk_button_new_with_label("2");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[2],1,2,5,6);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[2]), "clicked", G_CALLBACK (cb_affiche(Mon_Bouton[], Mon_Bouton[2])), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[3] = gtk_button_new_with_label("3");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[3],2,3,5,6);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[3]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[4] = gtk_button_new_with_label("4");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[4],0,1,4,5);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[4]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[5] = gtk_button_new_with_label("5");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[5],1,2,4,5);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[5]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[6] = gtk_button_new_with_label("6");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[6],2,3,4,5);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[6]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[7] = gtk_button_new_with_label("7");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[7],0,1,3,4);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[7]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[8] = gtk_button_new_with_label("8");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[8],1,2,3,4);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[8]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[9] = gtk_button_new_with_label("9");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[9],2,3,3,4);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[9]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[10] = gtk_button_new_with_label("=");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[10],3,4,5,7);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[10]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[11] = gtk_button_new_with_label("+");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[11],3,4,3,5);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[11]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[12] = gtk_button_new_with_label("-");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[12],3,4,1,3);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[12]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[13] = gtk_button_new_with_label("*");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[13],2,3,1,3);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[13]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[14] = gtk_button_new_with_label("/");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[14],1,2,1,3);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[14]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
    		*/
    		Mon_Bouton[15] = gtk_button_new_with_label(",");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[15],1,2,6,7);/*
    		g_signal_connect (G_OBJECT (Mon_Bouton[15]), "clicked", G_CALLBACK (Affiche), Ma_Zone_Texte);
     
    		*/
      /* Affichage de la fenetre principale et de toutes ses applications */
    	gtk_widget_show_all (Ma_Fenetre);
     
      /* Lancement de la boucle principale */
    	gtk_main ();
     
    return EXIT_SUCCESS;
    }
    *Ma fonction affiche (.c et .h):
    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
     
    #include "affiche.h"
    #include <stdio.h>
     
    void cb_affiche(GtkWidget *pBouton, gpointer user_data)
    {
    /*Je n'ai pas compris comment passer les paramètres sans les perdres et je ne saurais etre sur de selectionner le bon parametre lors du g_signal_connect*/
    }
     
     
    #ifndef AFFICHE_H
    #define AFFICHE_H
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <gtk/gtk.h>
     
    void cb_affiche(GtkWidget *pBouton, gpointer user_data);
     
    #endif
    Ce que j'essaye de faire concretement :
    Lorsque j'appuie sur le bouton "0" par exemple je voudrais qu'il s'affiche dans ma zone de texte (je rapelle que c'est une text_view, peut etre à tort mais bon...).

    Deja si j'arrivais a faire ça se serait super bien et pour la suite il faudra bien que je me débrouille un peu tout seul non mais ! ^^.
    Je remercie d'avance ceux qui vont jeter un oeil sur mon code.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Tu y es presque.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mon_Bouton[0] = gtk_button_new_with_label("0");
    gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[0],0,1,6,7);
    /*g_signal_connect (G_OBJECT (Mon_Bouton[0]), "clicked", G_CALLBACK (cb_affiche(Mon_Bouton[], Mon_Bouton[0])), Ma_Zone_Texte);*/
    Pour connecter un CALLBACK à un widget en fonction d'un signal donné il faut respecter en premier lieu le prototype du CALLBACK dicté par le signal choisi. Ici pas de problème. Ensuite il faut que le signal choisi soit bien un signal émit par le widget en question. Encore une fois pas de problème.

    Maintenant pour connecter tout ce petit monde on transmet seulement le nom de la fonction CALLBACK, sans ses paramètres. Aie, comment on fait alors pour les paramètres? C'est là que le pointeur générique gpointer user_data entre en action . On récupère dans ce pointeur ce que l'on a transmis comme dernier argument de la fonction g_signal_connect();.

    En résumé si tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_signal_connect (G_OBJECT (Mon_Bouton[0]), "clicked", G_CALLBACK (cb_affiche), Ma_Zone_Texte);
    tu va récupérer dans cb_affiche(); le pointeur Ma_Zone_Texte dans le pointeur générique gpointer user_data qu'il te suffira de caster pour l'utiliser.
    Dans le CALLBACK le premier argument est le widget bouton ayant recu le signal "clicked". Tu peux donc récupérer son label par exemple pour savoir quel chiffre (ou opération de ta calculette) a été appuyé.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 14
    Par défaut
    Merci de cette réponse plutôt claire, je vais enchaîner les tests et je reviens vous dire ce qu'il en ait.

    PS: ayant à mon grand désarroi quelque problème avec Linux je ne pourrais pas poster mes futures avancées (dommage pour moi)


    Je me demandais si mon GtkWidget *Mon_Bouton[] pouvait me donner un argument du type gpointer ? Parce que je voudrais mettre Mon_Bouton[valeur] dans user_data.
    Le but final étant, après appuie du bouton '0' (Mon_Bouton[0] pour moi),d'afficher la valeur 0 s'affiche dans la zone de texte !

    ==> Après quelques tests ça à l'air de fonctionner (Mon_Bouton[valeur] en tant que gpointer).
    Mais mon probleme maintenant est de récuperer Ma_Zone_Texte lors du g_signal_connect.

    PS 2 : En faite je pense ne pas avoir compris comment récuperer le label de mon Gtk_Button !

    PS 3 : Une petite précision (cela nous pourra pas être plus clair après j'espère ^^). J'ai vu sur internet (votre site en autre) beaucoup de choses : ce qui m'a le plus interpellé c'est l'utilisation du widgets de GtkTextBuffer.
    En effet ce que j'essaye de faire me parait tout à fait similaire.
    Sauf que au lieu de récupérer d'un buffer les caractères que l'ont va insérer dans le widgets GtkTextView (pour moi c'est Ma_Zone_Texte).
    Je souhaiterais récupérer "UN" caractère d'un wigdet GtkButton (ici, Mon_Bouton) pour l'insérer dans Ma_Zone_Texte.

    Ouffff voilà c'est fait (l'explication seulement ^^). Je peux aller me coucher.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Pour récupérer le label d'un GtkButton il faut utiliser la fonction const gchar *gtk_button_get_label ();.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 14
    Par défaut
    Me revoilà avec de nouveau tracas.

    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
     
    #include "affiche.h"
    #include <stdio.h>
     
    void cb_affiche(GtkButton *pBouton[TAILLE], gpointer user_data)
    {
         gchar* stock_clic = gtk_button_get_label (GTK_BUTTON(pBouton[TAILLE]));
         gint stock;
         stock = (gint)stock_clic;
         printf("%d", stock);
    }
    /*******Plus un peu du main******/
    /* Creation de la zone de texte */
    	Ma_Zone_Texte = gtk_text_view_new_with_buffer (Mon_Buffer);
    	gtk_table_attach_defaults (GTK_TABLE (Mon_Tableau), Ma_Zone_Texte, 0, 4, 0, 1);
     
     
    /* Voila le bouton sur lequel je fais mes tests*/
     
    		Mon_Bouton[0] = gtk_button_new_with_label("0");
    		gtk_table_attach_defaults(GTK_TABLE(Mon_Tableau),Mon_Bouton[0],0,1,6,7);
    		g_signal_connect (G_OBJECT (Mon_Bouton[0]), "clicked", G_CALLBACK (cb_affiche), Ma_Zone_Texte);
    et mon message d'erreur :
    <Nom_de_mon_projet.exe:3132>:Gtk-CRITICAL **: gtk_button_get_label: assertion `GTK_IS_BUTTON (button)' failed
    0 ==> c'est mon printf !

    J'espère qu'après avoir compris tout ça je pourrais faire quelques truc sympa!
    PS : si quelqu'un pourrait me préciser comment se fait un cast entre deux widgets, merci !
    ==> J'ai supposé que ça forcais un widget a passer à l'etat du widget parent pour communiquer avec un autre widget qui possede le meme parent

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    Erreur. Le pointeur que tu récupères en premier argument de la fonction void cb_affiche(GtkButton *pBouton[TAILLE], gpointer user_data)
    n'est pas un tableau. Il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void cb_affiche(GtkButton *pBouton, gpointer user_data)
    Ensuite la fonction gtk_button_get_label(); te renvoie un const gchar*. Déclare-le comme ca aussi.

    Enfin pButton est déjà du type GTK_BUTTON. Nul besoin de le caster à nouveau.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void cb_affiche(GtkButton *pBouton, gpointer user_data)
    {
         const gchar* stock_clic = gtk_button_get_label(pBouton);
    //     gint stock;
    //     stock = (gint)stock_clic;
         printf("%s\n", stock_clic);
    }
    Remarque:
    Si tu veux que les printf s'affichent pendant l'exécution il faut toujours faire un retour chariot (\n).

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 22/09/2006, 01h28
  2. Réponses: 10
    Dernier message: 23/03/2006, 20h57
  3. [Cookies] Mes cookies ne sont pas créés
    Par YavaDeus dans le forum Langage
    Réponses: 3
    Dernier message: 31/01/2006, 09h41
  4. [XSL] Mes entités ne sont pas prises en compte
    Par trent94 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 04/07/2005, 18h49
  5. [JSTL] Mes variables ne sont pas remplacées par leur valeur
    Par thomine dans le forum Taglibs
    Réponses: 9
    Dernier message: 18/03/2005, 10h00

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