Je te laisse juge :Citation:
Envoyé par dj.motte
http://emmanuel-delahaye.developpez.com/goret.htm
Version imprimable
Je te laisse juge :Citation:
Envoyé par dj.motte
http://emmanuel-delahaye.developpez.com/goret.htm
Merci beaucoup pour vos réponses.
J'ai beaucoup appris aujourd'hui :mouarf:
Sinon, une autre question, dans une fonction GTK je veux récupérer le chemin à l'extérieur de la fonction, cependant la fonction donné par GTK garde le chemin à l'intérieur de la fonction, il n'y a pas de return.
voilà le code:
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 void OnExplorer1(GtkWidget *pWidget, gpointer data) { GtkWidget *pFileSelection; // GtkWidget *pDialog; GtkWidget *pParent; gchar *sChemin1; pParent = GTK_WIDGET(data); /* Creation de la fenetre de selection */ pFileSelection = gtk_file_chooser_dialog_new("Ouvrir l'image...", GTK_WINDOW(pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE); /* Affichage fenetre */ switch(gtk_dialog_run(GTK_DIALOG(pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin1 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); // pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), // GTK_DIALOG_MODAL, // GTK_MESSAGE_INFO, // GTK_BUTTONS_OK, // "Chemin du fichier :\n%s", sChemin); // gtk_dialog_run(GTK_DIALOG(pDialog)); // gtk_widget_destroy(pDialog); // g_free(sChemin); break; default: break; } chemin1=sChemin1; gtk_widget_destroy(pFileSelection); }
J'ai mis en commentaires quelques lignes de code car je ne veux pas afficher le chemin mais plutôt le récupérer dans une variable.
Merci.
Citation:
Envoyé par zennn
La fonction je l'ai trouvé dans le Tutoriel de GTK, mais il parle pas d'une quelconque récupération de chemin :?
Moi je ne suis pas un styliste, mais un programmeur avec un peu de bon sens aurait fait ça :Citation:
Envoyé par dj.motte
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 const char *extract_name( const char *p, int sep ) { const char *z = NULL; if( p != NULL ) { z = strrchr(p, sep) ; if( z != NULL ) { z++ ; } } return z ; }
ben ton gpointer data sert justement à passer en entrée ou en sortie des données qui te sont propres...
Donc soit tu as juste besoin du chemin, et tu crées un char * quelque part au moment ou tu déclares la fonction, ou bien tu as une structure qui contient ce char, et tu passes l'adresse de la stucture à la place de data, et tu affectes cette variable char avec chemin..
C'est le principe même de ces fonctions de GUI événementiel...
J'ai pas très bien saisi.Citation:
Envoyé par souviron34
Le gpointer data n'est pas en * et donc on ne peut l'avoir en sortie, non?
Sinon pour le reste je n'ai pas très bien saisi.
Citation:
Envoyé par zennn
gpointer comme son nom l'indique est un POINTEUR.....
tu dois avoir quelque part
Dans les outils graphiques par événements (Delphi, XWindow, Window, Java, GTK..) chaue événement appelle une routine, caractérisée en général comme nterface par un id de "widget" (objet d'interface), éventuellement une structure propre à l'objet et/ou événement (callback structure), et un pointeur sur des données utilisateurs, qui peut se passer d'objet en objet.Code:typedef gpointer void*
En général, la manière de faire est de déclarer une structure statique comprenant les paramètres utilisateurs dans le main, et de passer l'adresse de cette structure dans les routines de l'outil (en la castant en void*, ou dans ton cas en gpointer).
Ensuite, quand on rentre dans la routine, il suffit de re-caster ce pointeur vers le pointeur de la bonne structure..
En général, un outil graphique possède une routine (en général une boucle) qui attend les événements (clics, appui sur un bouton, sur une liste, etcc..) et dispatch ensuite vers la bonne routine...
Exemple :
Voilà un petit exemple schématique...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 typedef PMASTRUCT { int Numero ; char *MonNom ; char *MonChemin ; .... } MASTRUCT ; static MASTRUCT Mienne ; int main (void) { ..... Mienne.Numero = 1 ; init_outil ( &Mienne); attend_evenement ( parametre_outil, (void*)&Mienne); } .... Bouton_Appuye ( Widget w, BoutonStructure *BStruct, void* data ) { MASTRUCT *Mienne = (MASTRUCT *)data ; Mienne->Numero = Mienne->Numero + 1 ; }
Merci pour l'explication.Citation:
Envoyé par souviron34
Je vais essayer ça.
C'est là qu'il faut apprendre à utiliser le paramètre 'data'.Citation:
Envoyé par zennn
Lors de l'installation de l'évènement, tu passes l'adresse d'une variable qui va être utilisée dans la fonction callback pour placer le résultat. Si c'est une chaine de caractères, il y a plusieurs solutions.
avecCode:
1
2
3
4 char chaine[BIG_ENOUGH]; on_event(..., callback, chaine);
ou bienCode:
1
2
3
4
5
6
7 void callback (..., gpointer data) { char *chaine = data; /* gpointer est en fait un 'void *' */ strcpy(data, mesinfos); }
avecCode:
1
2
3
4
5
6
7
8
9
10
11
12
13 struct mydata { char *chaine; }; struct mydata mydata = {0}; on_event(..., callback, &mydata); /* usage */ free (mydata.chaine), mydata.chaine = NULL;
etc.Code:
1
2
3
4
5
6
7 void callback (..., gpointer data) { struct mydata *p_data = data; p_data->chaine = strdup(mesinfos); }
Sauf que l'idée, avec le void *, est justement qu'il n'y a pas besoin de 'recaster'. Ca se fait tout seul depuis 1989... (ou alors, on ne parle pas de langage C...)Citation:
Envoyé par souviron34
C'est simple. Tu reprends la spec, tu envisages les cas possibles,Citation:
Envoyé par dj.motte
NULL
""
"abc"
"def/abc"
"def/abc.xyz"
abc"
"/def/abc"
"/def/abc.xyz"
"c:/"
"c:/abc"
"c:/def/abc"
"c:/def/abc.xyz"
"//"
"//abc"
"//def/abc"
"//def/abc.xyz"
etc.
tu fais un test unitaire qui teste tous ces cas et tu vois si ton code passe. C'est aussi simple que ça.
Quand au codage, ben, évite plus d'un return par fonction...
Salut
crocodilex propose :
Cette méthode ne garantit pas un retour sur NULL pour la fonction appelante dans certains cas limites.Code:
1
2
3
4
5
6
7
8
9 const char *extract_name( const char *p, int sep ) { const char *z = NULL; if( p != NULL ) { z = strrchr(p, sep) ; if( z != NULL ) { z++ ; } } return z ; }
J'ai apporté le correctif suivant, qui malheureusement propose deux "return", le code du goret, mais je ne vois pas comment contourner cette redondance de "return".
Code:
1
2
3
4
5
6
7
8
9
10
11
12 char * extract_name( const char *p, int sep ) { char *z = NULL; if( p != NULL ) { z = strrchr(p, sep) ; if( z != NULL ) { z++ ; if( *z == '\0' ) return NULL ; // ma correction } } return z ; }
Le probleme avec la correction est que l'on ne peut pas dire, vue la demande initiale, si elle apporte une correction ou introduit une erreur.Citation:
Envoyé par dj.motte
Le comportement que doit avoir la fonction si le caractere / se trouve en fin du chemin n'est pas specifier.
En l'etat de la demande retourner une chaine vide ne me semble pas specialement un plus mauvaise idee que de retourne NULL.
Tout simplement en remplacant return NULL; par z = NULL;Citation:
Envoyé par dj.motte
Citation:
Envoyé par Emmanuel Delahaye
Donc si j'ai bien compris, je dois déclarer un char *chemin; en dehors de la fonction OnExplorer, et à l'intérieur de cette fonction affecter le chemin à data.
Cependant lors du G_CALLBACK, je ne sais toujours pas comment passer chemin[GRAND] en paramètre dans la fonction, est ce qu'il faut le faire de cette manière?
Sinon, si on a plusieurs paramètres à faire passer comment faut-il procéder?Code:g_signal_connect(G_OBJECT(pExplorer1), "clicked", G_CALLBACK(OnExplorer1), chemin1);
Je vous montre mon code source:
J'ai sûrement fait des opérations inutile, le code est loin d'être optimisé :) mais comme je l'ai dit auparavant je débute en programmation :aie: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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 #include <stdlib.h> #include <gtk/gtk.h> static GtkWidget *pWindow; char *chemin1; char *chemin2; void OnExplorer1(GtkWidget *pWidget, gpointer data); void OnExplorer2(GtkWidget *pWidget, gpointer data); int main(int argc, char **argv) { GtkWidget *pButton1; GtkWidget *pButton2; GtkWidget *pButton3; GtkWidget *pExplorer1; GtkWidget *pExplorer2; GtkWidget *Morphint; GtkWidget *pTable; 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), 800, 600); g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL); // Creation de la table pour mettre les boutons pTable=gtk_table_new(8,6,TRUE); gtk_container_add(GTK_CONTAINER(pWindow),GTK_WIDGET(pTable)); pExplorer1=gtk_button_new_with_mnemonic("Explorer1..."); gtk_table_attach_defaults(GTK_TABLE(pTable),pExplorer1,0,2,7,8); g_signal_connect(G_OBJECT(pExplorer1), "clicked", G_CALLBACK(OnExplorer1), chemin1); pExplorer2=gtk_button_new_with_mnemonic("Explorer2..."); gtk_table_attach_defaults(GTK_TABLE(pTable),pExplorer2,2,4,7,8); g_signal_connect(G_OBJECT(pExplorer2), "clicked", G_CALLBACK(OnExplorer2), chemin2); Morphint=gtk_button_new_with_mnemonic("Morphint!!!"); gtk_table_attach_defaults(GTK_TABLE(pTable),Morphint,4,6,7,8); g_signal_connect(G_OBJECT(pExplorer2), "clicked", G_CALLBACK(morphint), chemin1); gtk_widget_show_all(pWindow); gtk_main(); return EXIT_SUCCESS; } void OnExplorer1(GtkWidget *pWidget, gpointer data) { GtkWidget *pFileSelection; // GtkWidget *pDialog; GtkWidget *pParent; gchar *sChemin1; pParent = GTK_WIDGET(data); /* Creation de la fenetre de selection */ pFileSelection = gtk_file_chooser_dialog_new("Ouvrir l'image...", GTK_WINDOW(pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE); /* Affichage fenetre */ switch(gtk_dialog_run(GTK_DIALOG(pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin1 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); data = sChemin1; // pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), // GTK_DIALOG_MODAL, // GTK_MESSAGE_INFO, // GTK_BUTTONS_OK, // "Chemin du fichier :\n%s", sChemin); // gtk_dialog_run(GTK_DIALOG(pDialog)); // gtk_widget_destroy(pDialog); // g_free(sChemin); break; default: break; } gtk_widget_destroy(pFileSelection); } void OnExplorer2(GtkWidget *pWidget, gpointer data) { GtkWidget *pFileSelection; // GtkWidget *pDialog; GtkWidget *pParent; gchar *sChemin2; pParent = GTK_WIDGET(data); /* Creation de la fenetre de selection */ pFileSelection = gtk_file_chooser_dialog_new("Ouvrir l'image...", GTK_WINDOW(pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE); /* Affichage fenetre */ switch(gtk_dialog_run(GTK_DIALOG(pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin2 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); data = sChemin2; // pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), // GTK_DIALOG_MODAL, // GTK_MESSAGE_INFO, // GTK_BUTTONS_OK, // "Chemin du fichier :\n%s", sChemin); // gtk_dialog_run(GTK_DIALOG(pDialog)); // gtk_widget_destroy(pDialog); // g_free(sChemin); break; default: break; } gtk_widget_destroy(pFileSelection); } void morphint () { char *commande; sprintf(commande,"morphint %s %s",file_name_src,file_name_des); system(commande); }
Merci.
Tu fabriques une structure (déjà dit !!) avec les éléments dont tu as besoin, et tu passes l'adresse comme data.Citation:
Envoyé par zennn
Exemple :
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 typedef pMaStruct { int toto ; double tata ; char *chemin ; } MaStruct ; int main(int argc, char **argv) { MaStruct MASTRUCTURE ; ..... MASTRUCTURE.toto = -1 ; MASTRUCTURE.tata = 10.5 ; MASTRUCTURE.chemin = strdup ("/home/ceci_est_mon_chemin"); ...... g_signal_connect1 (G_OBJECT(pExplorer2), "clicked", G_CALLBACK(morphint), &MASTRUCTURE); ..... } void g_signal_connect1 (..., gpointer data) { MaStruct *MyStruct = data; /* gpointer est en fait un 'void *' */ fprintf ( stderr, "\n TOTO %d TATA %g chemin %s\n", MyStruct->toto, MyStruct->tata, MyStruct->chemin); }
Je ne crois pas que tu ais compris...Citation:
Envoyé par zennn
J'ai pourtant pris la peine de préciser :
Ce qui, en clair, est un tableau de char d'une taille bien définie suffisamment grande pour le traitement voulu, et tu me parles de "déclarer un char *chemin;" Je parle mandarin ou quoi ?Code:char chaine[BIG_ENOUGH];
Donc il faut faire ceci :
Par défaut, la chaine est 'vide', mais dès que l'évènement se produit, elle prend la valeur que lui a donné l'évènement 'OnExplorer1()' (callback) :Code:
1
2
3
4
5 /* taille arbitraire, a toi de savoir ce que tu dois faire... */ chemin1[128] = ""; <...> g_signal_connect(G_OBJECT(pExplorer1), "clicked", G_CALLBACK(OnExplorer1), chemin1);
Je rappelle que pour copier une chaine, on utilise strcpy(). Cette méthode est correct mais il y a risque de débordement. On préfèrera la deuxième méthode que j'avais indiqué avec la structure, le pointeur sur char et strdup().Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 void OnExplorer1(GtkWidget *pWidget, gpointer data) { <...> gchar *sChemin1; case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin1 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); /* data = sChemin1; HORRIBLE ! */ strcpy (data, sChemin1); }
Avec une structure comme je l'ai montré (il n'y avait qu'un élément, mais on peut en mettre autant qu'on veut).Citation:
Sinon, si on a plusieurs paramètres à faire passer comment faut-il procéder?
Si tu débutes, il faut absolument que tu maitrises rapidement le concept de callback. Cet article donne un vision 'interne' du problème (GTK+ est une sorte d'assemblage de composants logiciels).Citation:
Je vous montre mon code source:
<...>
J'ai sûrement fait des opérations inutile, le code est loin d'être optimisé :) mais comme je l'ai dit auparavant je débute en programmation
http://emmanuel-delahaye.developpez.com/complog.htm
Bonsoir.
J'ai créé la structure, j'ai utilisé le strcpy cependant j'ai des messages d'erreur:
Code:
1
2
3
4
5
6
7
8
9
10
11
12 (programgtk:10008): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkWidget' (programgtk:10008): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkWindow' (programgtk:10008): Gtk-CRITICAL **: gtk_window_set_transient_for: assertion `parent == NULL || GTK_IS_WINDOW (parent)' failed (programgtk:10008): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkWidget' (programgtk:10008): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkWindow' (programgtk:10008): Gtk-CRITICAL **: gtk_window_set_transient_for: assertion `parent == NULL || GTK_IS_WINDOW (parent)' failed Erreur de segmentation (core dumped)
je remet le code source:
je fais mon possible pour corriger mes erreurs.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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 #include <stdlib.h> #include <gtk/gtk.h> static GtkWidget *pWindow; char chemin1[1000]; char chemin2[1000]; typedef struct { char *file_src; char *file_des; } srcdes; void OnExplorer1(GtkWidget *pWidget, gpointer data); void OnExplorer2(GtkWidget *pWidget, gpointer data); void morphint (srcdes fichiersEntree); int main(int argc, char **argv) { GtkWidget *pExplorer1; GtkWidget *pExplorer2; GtkWidget *Morphint; GtkWidget *pTable; srcdes fichiersEntree; 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), 800, 600); g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(gtk_main_quit), NULL); // Creation de la table pour mettre les boutons pTable=gtk_table_new(8,6,TRUE); gtk_container_add(GTK_CONTAINER(pWindow),GTK_WIDGET(pTable)); pExplorer1=gtk_button_new_with_mnemonic("Explorer1..."); gtk_table_attach_defaults(GTK_TABLE(pTable),pExplorer1,0,2,7,8); g_signal_connect(G_OBJECT(pExplorer1), "clicked", G_CALLBACK(OnExplorer1), chemin1); pExplorer2=gtk_button_new_with_mnemonic("Explorer2..."); gtk_table_attach_defaults(GTK_TABLE(pTable),pExplorer2,2,4,7,8); g_signal_connect(G_OBJECT(pExplorer2), "clicked", G_CALLBACK(OnExplorer2), chemin2); fichiersEntree.file_src = chemin1; fichiersEntree.file_des = chemin2; Morphint=gtk_button_new_with_mnemonic("Morphint!!!"); gtk_table_attach_defaults(GTK_TABLE(pTable),Morphint,4,6,7,8); g_signal_connect(G_OBJECT(Morphint), "clicked", G_CALLBACK(morphint), &fichiersEntree); gtk_widget_show_all(pWindow); gtk_main(); return EXIT_SUCCESS; } void OnExplorer1(GtkWidget *pWidget, gpointer data) { GtkWidget *pFileSelection; // GtkWidget *pDialog; GtkWidget *pParent; gchar *sChemin1; pParent = GTK_WIDGET(data); /* Creation de la fenetre de selection */ pFileSelection = gtk_file_chooser_dialog_new("Ouvrir l'image...", GTK_WINDOW(pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE); /* Affichage fenetre */ switch(gtk_dialog_run(GTK_DIALOG(pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin1 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); strcpy (data, sChemin1); // pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), // GTK_DIALOG_MODAL, // GTK_MESSAGE_INFO, // GTK_BUTTONS_OK, // "Chemin du fichier :\n%s", sChemin); // gtk_dialog_run(GTK_DIALOG(pDialog)); // gtk_widget_destroy(pDialog); // g_free(sChemin); break; default: break; } gtk_widget_destroy(pFileSelection); } void OnExplorer2(GtkWidget *pWidget, gpointer data) { GtkWidget *pFileSelection; // GtkWidget *pDialog; GtkWidget *pParent; gchar *sChemin2; pParent = GTK_WIDGET(data); /* Creation de la fenetre de selection */ pFileSelection = gtk_file_chooser_dialog_new("Ouvrir l'image...", GTK_WINDOW(pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal(GTK_WINDOW(pFileSelection), TRUE); /* Affichage fenetre */ switch(gtk_dialog_run(GTK_DIALOG(pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ sChemin2 = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pFileSelection)); strcpy (data, sChemin2); // pDialog = gtk_message_dialog_new(GTK_WINDOW(pFileSelection), // GTK_DIALOG_MODAL, // GTK_MESSAGE_INFO, // GTK_BUTTONS_OK, // "Chemin du fichier :\n%s", sChemin); // gtk_dialog_run(GTK_DIALOG(pDialog)); // gtk_widget_destroy(pDialog); // g_free(sChemin); break; default: break; } gtk_widget_destroy(pFileSelection); } void morphint (srcdes fichiersEntree) { char *commande; sprintf(commande,"morphint %s %s",fichiersEntree.file_src,fichiersEntree.file_des); }
Merci de votre aide.
Ca ne compile pas...Citation:
Envoyé par zennn
EDIT : en fait, j'ai réinstallé DevPak GTK+ et ça compile :
glib : 2.6.6
atk : 1.9.0
pango : 1.8.2
gtk+ : 2.6.9
par contre je ne suis pas sûr d'avoir le bon runtime...
Je me suis fait jeter. Il manque -mms-bitfields...
OK : Ouah, trop beau, l'explorateur :!:
OK. Quand je lance l'explorer1, j'obtiens :
Il doit y avoir des problèmes dans les paramètres des fonctions...Code:
1
2
3
4
5
6
7
8
9
10
11 (console.exe:1000): GLib-GObject-WARNING **: invalid unclassed pointer in cast t o `GtkWidget' (console.exe:1000): GLib-GObject-WARNING **: invalid unclassed pointer in cast t o `GtkWindow' (console.exe:1000): Gtk-CRITICAL **: gtk_window_set_transient_for: assertion `pa rent == NULL || GTK_IS_WINDOW (parent)' failed Press ENTER to continue.
Voilà, ça fonctionne. J'ai pas mal remanier l'affaire, organisé les données, simplifié (un seul explorer, pourquoi 2 ?), mis au point morphint... (trace dans la console)
Surtout, si tu ne comprends pas, tu poses des questions.
J'ai sélectionné 2 fichiers qui trainaient dans le répertoire courant. La trace :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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 #include <stdlib.h> #include <string.h> #include <gtk/gtk.h> struct exp { GtkWidget *pParent; char *chemin; }; struct fichiers { struct exp src; struct exp des; }; static void Explorer (GtkWidget * pWidget, gpointer data) { if (data != NULL) { struct exp *p_data = data; GtkWidget *pParent = GTK_WIDGET (p_data->pParent); /* Creation de la fenetre de selection */ GtkWidget *pFileSelection = gtk_file_chooser_dialog_new ("Ouvrir l'image...", GTK_WINDOW (pParent), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* On limite les actions a cette fenetre */ gtk_window_set_modal (GTK_WINDOW (pFileSelection), TRUE); /* Affichage fenetre */ switch (gtk_dialog_run (GTK_DIALOG (pFileSelection))) { case GTK_RESPONSE_OK: /* Recuperation du chemin */ { gchar *sChemin = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (pFileSelection)); p_data->chemin = strdup (sChemin); } break; default: ; } gtk_widget_destroy (pFileSelection); } (void) pWidget; } void morphint (GtkWidget * pWidget, gpointer data) { if (data != NULL) { struct fichiers *pFichiers = data; static const char cde[] = "morphint"; size_t size = sizeof cde + sizeof " " + strlen (pFichiers->src.chemin) + strlen (pFichiers->des.chemin); char *scommande = malloc (size); sprintf (scommande, "%s %s %s", cde, pFichiers->src.chemin, pFichiers->des.chemin); /* on libere les chaines initiales */ free (pFichiers->src.chemin), pFichiers->src.chemin = NULL; free (pFichiers->des.chemin), pFichiers->des.chemin = NULL; fprintf (stderr, "'%s'\n", scommande); free (scommande); } (void) pWidget; } int main (int argc, char **argv) { gtk_init (&argc, &argv); /* construction de la fenetre */ { GtkWidget *pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (pWindow != NULL) { gtk_window_set_title (GTK_WINDOW (pWindow), "GtkDialog"); gtk_window_set_default_size (GTK_WINDOW (pWindow), 800, 600); g_signal_connect (G_OBJECT (pWindow), "destroy", G_CALLBACK (gtk_main_quit), NULL); /* construction de l'interface */ { /* structure de donnee commune aux 3 boutons */ struct fichiers fichiers; /* Creation de la table pour mettre les boutons */ GtkWidget *pTable = gtk_table_new (8, 6, TRUE); gtk_container_add (GTK_CONTAINER (pWindow), GTK_WIDGET (pTable)); /* construction des 3 boutons */ fichiers.src.pParent = pWindow; fichiers.des.pParent = pWindow; /* source */ { GtkWidget *pButtonSrc = gtk_button_new_with_mnemonic ("Source..."); gtk_table_attach_defaults (GTK_TABLE (pTable), pButtonSrc, 0, 2, 7, 8); g_signal_connect (G_OBJECT (pButtonSrc), "clicked", G_CALLBACK (Explorer), &fichiers.src); } /* destination */ { GtkWidget *pButtonDes = gtk_button_new_with_mnemonic ("Destination..."); gtk_table_attach_defaults (GTK_TABLE (pTable), pButtonDes, 2, 4, 7, 8); g_signal_connect (G_OBJECT (pButtonDes), "clicked", G_CALLBACK (Explorer), &fichiers.des); } /* destination */ { GtkWidget *pButtonMorphint = gtk_button_new_with_mnemonic ("Morphint!!!"); gtk_table_attach_defaults (GTK_TABLE (pTable), pButtonMorphint, 4, 6, 7, 8); g_signal_connect (G_OBJECT (pButtonMorphint), "clicked", G_CALLBACK (morphint), &fichiers); } } gtk_widget_show_all (pWindow); } } gtk_main (); return EXIT_SUCCESS; }
(oui, je suis sous Windows, mais GTK+, c'est portable. C'est plutôt bien fait ct'affaire..)Code:
1
2
3
4 'morphint C:\dev\forums\lecture_hexa.c C:\dev\forums\main.c' Press ENTER to continue.
Citation:
Envoyé par Emmanuel Delahaye
Merci beaucoup pour ton aide, très précieux, je regarde ça de très près :)
Reste plus qu'à intégrer la fonction de récupération de nom en haut et le tour est joué.
Je vous tiens au courant!
Encore merci Emmanuel Delahaye :ccool:
Je vais continuer demain, car demain j'ai pas mal de trucs à faire.
Je vous tiendrez au courant.
:salut: