Pourrais-tu expliquer un peu plus ce que doivent faire exactement tes différents boutons. Par exemple le "copier" il copie quoi dans quoi ?
Pourrais-tu expliquer un peu plus ce que doivent faire exactement tes différents boutons. Par exemple le "copier" il copie quoi dans quoi ?
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Merci! Franchement c'est grâce à toi que j'y arrive han!
J'ai 2 petits problèmes:
-Quand il s'agit d'une image trop grande, elle prend toute la place et je ne sais pas comment l'en empêcher, j'ai un peu fouillé dans les paramètres de GTKIMAGE dans glade mais j'ai pas trouvé quelque chose qui limite la taille d'affichage.
-Secondo c'est toujours mon problème de copier, coller, couper, supprimer cité plus haut...
GtkImage ne peut pas grand chose pour toi.
Lorsque tu charges une image que tu veux "travailler" il faut passer par les GdkPixbuf. Tu as tout ce qu'il faut avec cette bibliothèque (intégrée à Gtk+) pour charger, modifier, enregistrer une image.
Tu as bien sûr aussi la possibilité de créer un GtkImage depuis un GdkPixbuf.
Je te laisse fouiller un peu la documentation : https://developer.gnome.org/gdk-pixbuf/stable/
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Pour l'image, j'ai réussi, j'ai modifier le callback_validate ainsi:
Pour le copier, coller, couper, supprimer, j'ai écris ceci et je ne comprends pas pourquoi seul le supprimer fonctionne...
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 void callback_validate(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkWidget *chooserdialog = NULL; chooserdialog=GTK_WIDGET (gtk_builder_get_object (data->builder, "FileChooserWindow")); char *filename; GtkFileChooser *chooser = GTK_FILE_CHOOSER(chooserdialog); filename = gtk_file_chooser_get_filename(chooser); //PIXBUFF GError **error=NULL; GdkPixbuf *image_pix = gdk_pixbuf_new_from_file_at_size (filename, WIDTH, HEIGHT, error); //affichage de l'image GtkImage *image = GTK_IMAGE(gtk_builder_get_object(data->builder,"Image")); gtk_image_set_from_pixbuf (image, image_pix); gtk_widget_hide(chooserdialog); }
Est ce que ce n'est pas parce que le clipboard est défini globalement? Voici le code source:
Ps: Je cherche à reproduire dans mes boutons, les raccourcis: ctrl+C, ctrl+V, ctrl+X, supp. Ce sera évidemment pour le text view.
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 GtkClipboard *clipboard = NULL; void callback_cut (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE); } void callback_copy (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_copy_clipboard (buffer, clipboard); } void callback_paste (GtkMenuItem *menuitem, gpointer user_data) { if (clipboard != NULL) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE); } } void callback_delete (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); }
Aussi, lorsque l'OCR fini son travail et saisi le texte dans le "TextView", je veux pouvoir récupérer le texte et l'enregistrer dans un ficher texte (.txt) à travers l’option enregistrer sous dans une des sections de la barre de menu.
J'ai donc écris le code suivant:
Mais j’obtiens cette erreur à la fin et je ne sais pas pourquoi? J'utilise surement mal les GtkTextIter. Que dois-je faire?
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 void callback_saveas(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } gint res; SGlobalData *data = (SGlobalData*) user_data; GtkWidget *save_as = NULL; save_as= GTK_WIDGET (gtk_builder_get_object (data->builder, "FileSaveWindow")); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER(save_as),("Untitled document")); res = gtk_dialog_run (GTK_DIALOG (save_as)); } void callback_save(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkWidget *chooserdialog = NULL; chooserdialog=GTK_WIDGET (gtk_builder_get_object (data->builder, "FileSaveWindow")); char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooserdialog)); //IMPLEMENTER ICI LA FONCTION POUR RECUPERER LE TEXTE ET LE SAUVEGARDER gint count = 0; GtkTextIter *start=NULL; GtkTextIter *end=NULL; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_get_start_iter (buffer, start); gtk_text_buffer_get_end_iter (buffer, end); count = gtk_text_buffer_get_char_count (buffer); //saveas(filename, buffer, start, end, count); gtk_widget_hide (chooserdialog); } void callback_cancel2(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkWidget *chooserdialog = NULL; chooserdialog=GTK_WIDGET (gtk_builder_get_object (data->builder, "FileSaveWindow")); gtk_widget_hide(chooserdialog); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 (main:5752): Gtk-CRITICAL **: gtk_text_buffer_get_start_iter: assertion 'iter != NULL' failed (main:5752): Gtk-CRITICAL **: gtk_text_buffer_get_end_iter: assertion 'iter != NULL' failed
C'est la bonne démarche. Cependant lorsque tu crées un GdkPixbuf tu alloues de la mémoire dans le tas (malloc). Il te faut donc la libérer avant que ta fonction se termine.
Une fois le GtkImage créé avec le GdkPixbuf il te suffit de faire g_object_unref(image_pix);.
Tu n'as pas bien compris l'utilisation du pointeur error. Le type GError est une structure qui sera initialisée si une erreur survient. Pour se faire il faut transmettre l'adresse d'un pointeur initialisé à NULL. L'idée est de simuler la gestion d'exception try/catch des langages OO. Ton code doit ressembler plus à ca.
Tu auras ainsi un message en console dans le canal stderr explicite sur le problème survenu. Essaies-le en spécifiant un nom de fichier fantaisiste pour le GdkPixbuf.
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 //PIXBUF GError *error=NULL; GdkPixbuf *image_pix = gdk_pixbuf_new_from_file_at_size (filename, WIDTH, HEIGHT, &error); // Si le pointeur error est différent de NULL alors une erreur est survenue if (error) { g_printerr ("%s\n", error->message); // Libération de la mémoire allouée pour error g_error_free (error); } else { //affichage de l'image GtkImage *image = GTK_IMAGE(gtk_builder_get_object(data->builder,"Image")); gtk_image_set_from_pixbuf (image, image_pix); // Libération du GdkPixbuf g_object_unref(image_pix); } gtk_widget_hide(chooserdialog);
Hormis la fonction callback_delete(); tu utilises dans les autres un pointeur clipboard. Où est-il initialisé ?
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Pour enregistrer le text saisi, j'ai finalement réussi, j'initialisais mal mes GtkTextIter en fait.
Ma fonction est donc celle-ci finalement:
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 void callback_save(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkWidget *chooserdialog = NULL; chooserdialog=GTK_WIDGET (gtk_builder_get_object (data->builder, "FileSaveWindow")); char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooserdialog)); //IMPLEMENTER ICI LA FONCTION POUR RECUPERER LE TEXTE ET LE SAUVEGARDER gint count = 0; GtkTextIter start; GtkTextIter end; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_get_start_iter (buffer, &start); gtk_text_buffer_get_end_iter (buffer, &end); count = gtk_text_buffer_get_char_count (buffer); saveas(filename, buffer, start, end, count); gtk_widget_hide (chooserdialog); }
Tu t'emmêles un peu les pinceaux entre les variables et le pointeurs. Cette notion ne semble pas encore très claire.
Un iter est un index. Tu peux l'imaginer comme un nombre (ce n'est pas vraiment le cas). Les fonctions gtk_text_buffer_get_start_iter (buffer, start); et gtk_text_buffer_get_end_iter (buffer, end); vont te retourner l'index de départ et de fin du texte. Mais pour pouvoir te les retourner il faut lui transmettre les adresses respectives des variables que tu désires manipuler. Ce qui donne :
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 void callback_save(GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkWidget *chooserdialog = NULL; chooserdialog=GTK_WIDGET (gtk_builder_get_object (data->builder, "FileSaveWindow")); char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(chooserdialog)); //IMPLEMENTER ICI LA FONCTION POUR RECUPERER LE TEXTE ET LE SAUVEGARDER gint count = 0; GtkTextIter start; GtkTextIter end; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); gtk_text_buffer_get_start_iter (buffer, &start); gtk_text_buffer_get_end_iter (buffer, &end); count = gtk_text_buffer_get_char_count (buffer); //saveas(filename, buffer, start, end, count); gtk_widget_hide (chooserdialog); }
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Le clip board est initialisé en global avant toutes les fonctions, regarde la première ligne, je l'ai mi.
Oui, les pointeurs je ne maîtrise pas encore super bien. Mais t'as vu j'ai résolu le problème de mes gtktextiter quelques minutes avant ta publication!^^
Beurk ! Pas de variable globale. Ton code va devenir incompréhensible et source d'erreurs.
Ceci dit tu transmets un cliboard NULL. Comment veux-tu travailler dessus ? Je pense qu'il faut passer par ce genre de fonctions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part GtkClipboard *gtk_clipboard_get (GdkAtom selection);
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
En fait je me demandais comment est-ce que mes fonctions copy et paste vont pouvoir utiliser le même clipboard....
Aussi j'ai jeté un coup d'oeil à la fonction GtkClipboard *gtk_clipboard_get (GdkAtom selection); mais le GdkAtom je le tire d'où? Ou il faut que je le l'initialise?
Je n'ai jamais utilisé le clipboard. Je découvre en même temps que toi. À priori tu peux utiliser la fonction gdk_atom_intern(); pour récupérer l'atom courant ou en créé un. Cependant il semble qu'il ne peut y avoir qu'un seul atom par processus (ton application). Tu dois pouvoir aussi utiliser l'atom général géré par le serveur X (qui te permets de faire des copier/coller d'une application à une autre).
En partant de ce principe j'ajouterai un GdkAtom à ta structure principale SGlobalData et je l'initialiserai en début de programme. Ainsi tu y accèdes en tout point du programme et tu supprimes cette déclaration en globale hideuse .
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Voici ce que j'ai fait:
J'ai ajouter donc le GdkAtom à la structure ainsi:
Puis je l'ai initialisé dans la fonction main ainsi:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 typedef struct { GtkBuilder *builder; gpointer user_data; GdkAtom selection; } SGlobalData;
Puis j'ai re écris mes fonctions copier coller et couper ainsi:
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 int main(int argc, char *argv []) { GtkWidget *fenetre_principale = NULL; SGlobalData data; GError *error = NULL; gchar *filename = NULL; //INITIALISATION GDKATOM (CLIPBOARD) data.selection = NULL; /* Initialisation de la bibliothèque Gtk. */ gtk_init(&argc, &argv); /* Ouverture du fichier Glade de la fenêtre principale */ data.builder = gtk_builder_new(); /* Création du chemin complet pour accéder au fichier test.glade. */ /* g_build_filename(); construit le chemin complet en fonction du système */ /* d'exploitation. ( / pour Linux et \ pour Windows) */ filename = g_build_filename (UI_FILE, NULL); /* Chargement du fichier Volcarm_OCR.glade. */ gtk_builder_add_from_file (data.builder, filename, &error); g_free (filename); if (error) { gint code = error->code; g_printerr("%s\n", error->message); g_error_free (error); return code; } /* Affectation des signaux de l'interface aux différents CallBacks. */ gtk_builder_connect_signals (data.builder, &data); /* Récupération du pointeur de la fenêtre principale */ fenetre_principale = GTK_WIDGET(gtk_builder_get_object (data.builder, "MainWindow")); /* Affichage de la fenêtre principale. */ gtk_widget_show_all (fenetre_principale); gtk_main(); return 0; }
Résultat, couper et copier ne marchent pas. Par contre coller marche, si je copie n'importe quoi de n'importe ou, meme depuis internet et que j'ouvre le programme et que je colle dans le textview, il me colle parfaitement ce que j'ai copié quelque soit l'endroit d'où je l'ai copié.
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 void callback_cut (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); GtkClipboard *clipboard = gtk_clipboard_get(data->selection); gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE); } void callback_copy (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); GtkClipboard *clipboard = gtk_clipboard_get(data->selection); gtk_text_buffer_copy_clipboard (buffer, clipboard); } void callback_paste (GtkMenuItem *menuitem, gpointer user_data) { if (menuitem != NULL) { } SGlobalData *data = (SGlobalData*) user_data; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtk_builder_get_object(data->builder, "TextView"))); GtkClipboard *clipboard = gtk_clipboard_get(data->selection); if(clipboard!=NULL) { gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE); } }
Il n'arrive donc pas à couper ni copier une sélection du textview...
Ah non finalement ça marche. C'est moi, j'avais juste oublier de connecter mes boutons couper et copier du menu à leurs callbacks respectifs. Impeccable.
Bien maintenant, je vais pouvoir assembler le code de mon interface avec celui de mon programme.
Mais avant, une dernière chose, pour la fenêtre about, pourquoi j'obtiens un "Impossible d'afficher le lien" et "Opération non prise en charge" quand je clique sur le lien du site web...?
Il peut y avoir deux possiblités je pense :
- tu n'as pas correctement initialisé l'adresse de l'url,
- ton bureau est mal configuré. Il ne sait pas quoi lancer comme application avec ton adresse web.
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager