problème fonctions callback
bonjour,
pourquoi n'est-il pas possible de placer les fonctions call_back dans d'autres fichiers.c ???
le prototype des fonctions étant déclaré
si c'est possible cmment faire merci
Re: gtk+ => problème fonctions callback
Citation:
Envoyé par youp_db
pourquoi n'est-il pas possible de placer les fonctions call_back dans d'autres fichiers.c ???
le prototype des fonctions étant déclaré
Comme pour n'importe quelle fonction publique, pour être propre et cohérent, le prototype séparé doit être placé dans un fichier protégé par des gardes anti-inclusion multiples, et inclus dans le fichier de définition de la fonction et dans tous les fichiers d'utilisation, selon ce modèle bien connu :
http://emmanuel-delahaye.developpez....ganiser_source
http://emmanuel-delahaye.developpez.....htm#organiser
Citation:
si c'est possible cmment faire merci
Normalement, on peut. (à moins qu'il y ait un 'static' caché dans la macro G_POINTER()...)
Je ne vois rien qui empèche de mettre la fonction ailleurs. Comme ça, par exemple (horrible ces globales...).
Code:
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
|
/* main.c */
#include <stdlib.h>
#include <gtk/gtk.h>
#include "cb_boite.h"
static GtkWidget *pLabel;
static GtkWidget *pWindow;
int main(int argc, char **argv)
{
GtkWidget *pVBox;
GtkWidget *pButton;
gtk_init(&argc, &argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "GtkDialog");
gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL);
pVBox = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(pWindow), pVBox);
pButton = gtk_button_new_with_label("Cliquez ici pour saisir votre nom");
gtk_box_pack_start(GTK_BOX(pVBox), pButton, FALSE, TRUE, 0);
pLabel = gtk_label_new(NULL);
gtk_box_pack_start(GTK_BOX(pVBox), pLabel, FALSE, FALSE, 0);
/* Connexion du signal "clicked" pour ouvrir la boite de dialogue */
g_signal_connect(G_OBJECT(pButton), "clicked", G_CALLBACK(LancerBoite), NULL);
gtk_widget_show_all(pWindow);
gtk_main();
return EXIT_SUCCESS;
} |
Code:
1 2 3 4 5 6 7
|
#ifndef H_CB_BOITE
#define H_CB_BOITE
void LancerBoite(void);
#endif |
Code:
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
|
/* cb_boite.c */
#include "cb_boite.h"
void LancerBoite(void)
{
GtkWidget* pBoite;
GtkWidget* pEntry;
const gchar* sNom;
/* Creation de la boite de dialogue */
/* 1 bouton Valider */
/* 1 bouton Annuler */
pBoite = gtk_dialog_new_with_buttons("Saisie du nom",
GTK_WINDOW(pWindow),
GTK_DIALOG_MODAL,
GTK_STOCK_OK,GTK_RESPONSE_OK,
GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,
NULL);
/* Creation de la zone de saisie */
pEntry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(pEntry), "Saisissez votre nom");
/* Insertion de la zone de saisie dans la boite de dialogue */
/* Rappel : paramètre 1 de gtk_box_pack_start de type GtkBox */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pBoite)->vbox), pEntry, TRUE, FALSE, 0);
/* Affichage des elements de la boite de dialogue */
gtk_widget_show_all(GTK_DIALOG(pBoite)->vbox);
/* On lance la boite de dialogue et on recupere la reponse */
switch (gtk_dialog_run(GTK_DIALOG(pBoite)))
{
/* L utilisateur valide */
case GTK_RESPONSE_OK:
sNom = gtk_entry_get_text(GTK_ENTRY(pEntry));
gtk_label_set_text(GTK_LABEL(pLabel), sNom);
break;
/* L utilisateur annule */
case GTK_RESPONSE_CANCEL:
case GTK_RESPONSE_NONE:
default:
gtk_label_set_text(GTK_LABEL(pLabel), "Vous n'avez rien saisi !");
break;
}
/* Destruction de la boite de dialogue */
gtk_widget_destroy(pBoite);
} |
Ok, ça ne compile pas à cause des défintions globales. Je ne connais pas les détails de GTK+, mais il y a fort à parier que les callbacks peuvent être appeler avec un parametre de type (void*) qui reçoit l'adresse passée lors de l'installation de celui-ci (qui vaut NULL pour le moment) :
Code:
1 2
|
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL); |
Que je modifierais en
Code:
1 2
|
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), pWindow); |
Dans le callback :
Code:
1 2 3 4 5 6 7 8 9 10 11
|
void LancerBoite (void *p_user)
{
GtkWidget *pWindow = *p_user;
if (pWindow != NULL)
{
GtkWidget* pBoite;
GtkWidget* pEntry;
const gchar* sNom;
<...> |
Bien sûr, il faut modifier le prototype en conséquence, et retirer ce G_CALLBACK() qui ne fait que cacher la vérité...
Code:
g_signal_connect(G_OBJECT(pWindow), "destroy", gtk_main_quit, pWindow);
etc.
Un peu de théorie sur les callbacks...
http://emmanuel-delahaye.developpez.com/complog.htm