voila, je veux afficher à intervalle regulier des images dans une cellule d'un ptable d'une fenetre avec gtk thread sous c sans que le programme principale soit géné. quelqu'un peut il suggérer une réponse?
merci.
voila, je veux afficher à intervalle regulier des images dans une cellule d'un ptable d'une fenetre avec gtk thread sous c sans que le programme principale soit géné. quelqu'un peut il suggérer une réponse?
merci.
La bonne solution (la plus simple) est d'utiliser la fonction g_timeout_add(); ou une de ses dérivées. Tu peux grâce à elle exécuter une fonction à intervalle régulier sans gêner la boucle principale de Gtk+ tout en interférant directement avec l'interface graphique.
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
excusez moi, mais je n'ai pas réussi a faire marcher ce programme. j'ai fait de la lecture du forum, je n'ai pas capté encore. voici un exemple trouvé dans le forum et que j'ai adapté, mais qui ne fonctionne pas:
#include<glib.h>
#include<gtk/gtk.h>
#include<gdk-pixbuf/gdk-pixbuf.h>
#include<gthread.h>
GtkWidget *image0,*image;
static gpointer thread_func(gpointer data)
{
gint i;
gchar tmp0[50],tmp1[50];
for( i = 0; i < 6; i++ )
{
g_usleep( 10000 );
//sprintf(tmp0,"img0%d.png",(i-1));
//g_object_ref((gpointer)tmp0);
sprintf(tmp1,"img0%d.png",i);
}
return( NULL );
}
static gboolean cb_timeout(gpointer data)
{
GtkButton *but;
gtk_button_set_image(GTK_BUTTON(but),image);
return(TRUE);
}
int main( int argc,char **argv )
{
GtkWidget *window;
GtkWidget *button;
GThread *thread;
GError *error = NULL;
// Secure glib
if( ! g_thread_supported() )
g_thread_init( NULL );
//Do stuff as usual
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
g_signal_connect( G_OBJECT( window ), "destroy",G_CALLBACK( gtk_main_quit ), NULL );
button = gtk_button_new();
gtk_container_add( GTK_CONTAINER( window ),button);
//g_timeout_add (500,cb_timeout,(gpointer)button);
//gdk_threads_add_timeout( 100, cb_timeout, (gpointer)button );
// Create new thread
thread = g_thread_create( thread_func, (gpointer)button,FALSE, &error );
if( ! thread )
{
g_print( "Error: %s\n", error->message );
return( -1 );
}
gtk_widget_show_all( window );
gtk_main();
return( 0 );
}
j'aimerai faire aparaitre ces images la 1ière, la 2ième,.... chacune une seconde et rebelote. voila mon idée svp.
merci de votre reponse.
Bon, utiliser les gThreads pour inter-agir avec une fenêtre c'est une très mauvaise idée.
Il faut utiliser les g_timeout_add();. Donc en partant de ce postulat commençons par appeler la fonction callback :
À partir de là on peut construire un code simple pour te montrer. Ce code ne me plait pas totalement puisque dans la fonction callback appelée j'initialise à chaque itération les images à insérer. Mais le but ici est de voir comment tout ce petit monde fonctionne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part g_timeout_add_seconds (1, (GSourceFunc)cb_timeout, button);
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 #include<gtk/gtk.h> static gboolean cb_timeout(GtkWidget *button) { static gboolean bascule = FALSE; GtkWidget *image0,*image; image0 = gtk_image_new_from_icon_name ("go-previous", GTK_ICON_SIZE_BUTTON); image = gtk_image_new_from_icon_name ("go-next", GTK_ICON_SIZE_BUTTON); if (!bascule) gtk_button_set_image(GTK_BUTTON(button), image0); else gtk_button_set_image(GTK_BUTTON(button), image); bascule = !bascule; return TRUE; } int main( int argc,char **argv ) { GtkWidget *window; GtkWidget *button; //Do stuff as usual gtk_init( &argc, &argv ); window = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_window_set_default_size(GTK_WINDOW(window), 500, 400); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); g_signal_connect( G_OBJECT( window ), "destroy",G_CALLBACK( gtk_main_quit ), NULL ); button = gtk_button_new(); gtk_container_add( GTK_CONTAINER( window ),button); // Insertion d'un callback dans la boucle Gtk+ avec une exécution toutes les secondes environ g_timeout_add_seconds (1, (GSourceFunc)cb_timeout, button); gtk_widget_show_all( window ); gtk_main(); return( 0 ); }
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 beaucoup, ça fonctionne mais seulement avec 2 images. est ce qu'on peut réutiliser plusieurs fois "g_timeout_add()"?
j'ai remodifié votre prog pour afficher 5 images. il n'y a pas de pbs, mais juste la dernière image s'affiche. le voici:
#include<gtk/gtk.h>
GtkWidget *envoi_img(guint i)
{
GtkWidget *image0;
gchar tmp[50];
sprintf(tmp,"img0%d.png",i);
image0 = gtk_image_new_from_file(tmp);
return image0;
}
static gboolean cb_timeout(GtkWidget *button)
{
gint i;
GtkWidget *image;
for(i=0;i<6;i++)
{
g_usleep(10000);
image = envoi_img(i);
gtk_button_set_image(GTK_BUTTON(button), image);
}
return TRUE;
}
int main( int argc,char **argv )
{
GtkWidget *window;
GtkWidget *button;
//Do stuff as usual
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
g_signal_connect( G_OBJECT( window ), "destroy",G_CALLBACK( gtk_main_quit ), NULL );
button = gtk_button_new();
gtk_container_add( GTK_CONTAINER( window ),button);
// Insertion d'un callback dans la boucle Gtk+ avec une exécution toutes les secondes environ
//g_timeout_add_seconds(1, (GSourceFunc)cb_timeout, button); ne fonctionne pas pour moi
g_timeout_add(100, (GSourceFunc)cb_timeout, button); fonctionne pour moi
gtk_widget_show_all( window );
gtk_main();
return( 0 );
}
on ne peut plus simple (si ? )
Bien sûr tu peux modifier le délai du timeout et le nombre d'images à afficher (ici 5)
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 #include <gtk/gtk.h> #include <glib.h> #include <glib-object.h> #include <string.h> #include <stdlib.h> typedef struct _Block Block; struct _Block { gint index; GtkImage* image; }; static gboolean show_image (Block* block) { block->index++; if (block->index == 5) block->index = 0; g_object_set (block->image, "file", g_strdup_printf ("/path/to/%d.png", block->index), NULL); return TRUE; } int main (int argc, char ** argv) { gtk_init (&argc, &argv); GtkWindow* win = (GtkWindow*) gtk_window_new (GTK_WINDOW_TOPLEVEL); Block block = {0}; memset (&block, 0, sizeof (Block)); block.image = (GtkImage*) gtk_image_new_from_file (g_strdup_printf ("/path/to/%d.png", block.index)); g_timeout_add (800, show_image, &block); gtk_container_add ((GtkContainer*) win, (GtkWidget*) block.image); gtk_widget_show_all ((GtkWidget*) win); gtk_main(); return 0; }
Attention ligne 18 et ligne 27 il y a une allocation mémoire dans le tas qui est perdue (les g_strdup_printf();).
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 énormement pour vos réponses. avant de clore cette discussion,
j'aimerai revenir sur le dernier prog qui a l'avantage de ne pas
limiter le nombre d'images et ceci sans utiliser de "button" pour insérer l(image dans la fenêtre.
mais il ne fonctionne pas pour moi!! il affiche la 1ière image et
reste bloqué.
g_object_set (block->image, "file", g_strdup_printf ("img0%d.png", block->index), NULL);
est ce exact? car img0%d.png est dans le même repertoire que le prg.
pareil pour:
block.image = (GtkImage*)gtk_image_new_from_file (g_strdup_printf ("img0%d.png",block.index));
de même,
g_timeout_add (800, show_image, &block);m'affiche une erreur:
Dev-Cpp\bin\test0_gtk.cpp invalid conversion from `gboolean (*)(Block*)' to `gboolean (*)(void*)'
voila, merci encore infiniment!!
Ah mais si tu précise pas c++ aussi . Dans ce cas tu vas devoir convertir la fonction source :
Code : Sélectionner tout - Visualiser dans une fenêtre à part g_timeout_add (800, (GSourceFunc)show_image, &block);
thanks tout le monde. on peut considérer que la question est résolu.
merci à tout le monde.
Bonjours d_wais et soit la bienvenue au club, voyant que tu est un nouveau venus.
Malgré le gros panneaux de gérald3d tu n'a mis ton code en forme (coloration syntaxique, indentation, etc...)
Car personne ne t'a correctement expliquer qu'il faut utiliser le bouton dièse '#' de l'interface d'écriture du club pour faire apparaître 2 balises:
-) [ CODE ] (balise ouvrante).
-) [ \CODE ] (balise fermante).
Entre lesquelles écrire ou copier-coller ton code source.
Puis si tu recherche la performance concernant l'affichage des images tu peut passer par un GdkBuffer, si tu ne passe pas par des fichiers.
Car cette nuit j'ai fait blinker lena.
Entre le gris et le coloré comme ça (avec un timeout) a la vitesse de une milliseconde par changement de couleurs...
En espérant que tu restera au club ou passe nous voir de temps en temps:
c'est le meilleur forum de programmation francophone visité quotidiennement par 2.2 millions de visiteurs.
Pour faire tes armes:
Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
Et sois toujours bien armé avant de te lancer.
Le hasard ne sourit qu'aux gens préparés...
Site: Website programmation international (www.open-source-projects.net)
Site: Website imagerie 3D (www.3dreaming-imaging.net)
Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
FUN is HARD WORK !!!
je reviens si vous me le permettez encore une fois sur ce sujet. je pensais l'avoir bouclé pour des bons, mais quelque chose me tracasse encore!!
je cherche à rendre un peu joli la fenetre. pour cela, je commence à afficher qques images.
- d'abord, une première affichage des 5 images avec g_timeout_add fonctionne bien.
- mais, une deuxième affichage des 5 autres images avec un autre g_timeout_add ne fonctionne pas du tout. seule la 1ière image reste affichée dans la case du tableau.
- si je cherche à afficher 1 image statique dans le coin supérieur gauche, celle ci bloque la fenetre. j'aimerai comprendre cela si possible. voici le code :
[]
#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<glib.h>
#include <glib-object.h>
#include<gtk/gtk.h>
#include<gthread.h>
typedef struct {
gint index;
GtkImage *image;
}Block;
Block block;
typedef struct {
gint index0;
GtkImage *imge0;
}Block0;
Block0 block0;
static gboolean show_image (Block *block) //GtkWidget *pButton1,
{
block->index++;
if(block->index == 5)
block->index = 0;
g_object_set(block->image, "file", g_strdup_printf("0%d.png",block->index), NULL);
g_free(block->image);
return TRUE;
}
//----------------------------------------------------------------------------------------------------------------------
static gboolean show_image_0 (Block0 *block0)
{
block0->index0++;
if(block0->index0 == 5)
block0->index0 = 0;
g_object_set(block0->imge0, "file", g_strdup_printf("00%d.png",block0->index0), NULL);
g_free(block0->imge0);
return TRUE;
}
//----------------------------------------------------------------------------------------------------------------------
int main(int argc,char **argv)
{
GtkWidget *Window;
GtkWidget *ptable;
GtkWidget *pimage;
GtkWidget *pButton;
gtk_init(&argc, &argv);
Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(Window), "Traffic_Window");
gtk_window_set_default_size(GTK_WINDOW(Window), 600, 800);
gtk_window_move(GTK_WINDOW(Window),10,30);
gtk_signal_connect_object(GTK_OBJECT(Window), "destroy", (GtkSignalFunc)gtk_exit, NULL);
//Creation et insertion de la table 4 lignes 5 colonnes
ptable=gtk_table_new(4,5,TRUE);
gtk_container_add(GTK_CONTAINER(Window), GTK_WIDGET(ptable));
//insertion d'image dans la fenetre
pimage = gtk_image_new_from_file("img0.png");
gtk_table_attach(GTK_TABLE(ptable), pimage,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0, 0);
// mais ceci ne marche pas!!
// il faut inserer l'image dans un button comme ceci:
pButton = gtk_button_new();
gtk_button_set_image(GTK_BUTTON(pButton1),pimage);
gtk_table_attach(GTK_TABLE(ptable), pButton1,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0, 0);
Block block = {0};
memset (&block, 0, sizeof(Block));
block.image = (GtkImage*)gtk_image_new_from_file (g_strdup_printf ("img1.png",block.index));
g_free(block.image);
g_timeout_add(300,(GSourceFunc)show_image,&block);
gtk_table_attach(GTK_TABLE(ptable), (GtkWidget*)block.image,2, 3, 0, 1,GTK_EXPAND,GTK_EXPAND,0, 0);
//s'affiche bien sans problème.
Block0 block0 = {0};
memset (&block0, 0, sizeof(Block0));
block0.imge0 = (GtkImage*)gtk_image_new_from_file (g_strdup_printf ("img2.png",block0.index0));
//g_free(block0.imge0);-> pose problème et fait aborter le programme!!
//g_timeout_add(300,(GSourceFunc)show_image_0,&block0); -> pose problème et fait aborter le programme!!
gtk_table_attach(GTK_TABLE(ptable), (GtkWidget *)block0.imge0,4, 5, 0, 1,GTK_EXPAND,GTK_EXPAND,0,0);
gtk_widget_show_all(Window);
gtk_main();
return EXIT_SUCCESS;
}
[/]
oui maintenant, j'y arrive pour l'histoire de la "dièse"!!!!
et pour ce qui concerne le code, après plusieurs recherches, ce code ci-dessous fonctionne sur 2 places différentes du tableau ptable. c'est comme je voulais, mais à l'excution et après le bouton "clicked", les defilements s'arrêtent. il faut des threads pour faire fontionner les boucles en parallèles. voilà cette question s'arrête definitivement!!!
merci à tous....
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 #include<stdlib.h> #include<stdio.h> #include<conio.h> #include<string.h> #include<glib.h> #include <glib-object.h> #include<gtk/gtk.h> #include<gthread.h> typedef struct { gint index; GtkImage *imge0; GtkImage *imge1; }Block; Block block; static gboolean show_image (Block *block) //GtkWidget *pButton1, { block->index++; if(block->index == 10) block->index = 0; g_object_set(block->imge0, "file", g_strdup_printf("0%d.png",block->index), NULL); g_free(block->imge0); g_object_set(block->imge1, "file", g_strdup_printf("0%d.png",block->index), NULL); return TRUE; } int main(int argc,char **argv) { GtkWidget *Window; GtkWidget *ptable; GtkWidget *pimage; GtkWidget *pButton; gtk_init(&argc, &argv); Window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(Window), "Traffic_Window"); gtk_window_set_default_size(GTK_WINDOW(Window), 600, 800); gtk_window_move(GTK_WINDOW(Window),10,30); gtk_signal_connect_object(GTK_OBJECT(Window), "destroy", (GtkSignalFunc)gtk_exit, NULL); //Creation et insertion de la table 4 lignes 5 colonnes ptable=gtk_table_new(4,5,TRUE); gtk_container_add(GTK_CONTAINER(Window), GTK_WIDGET(ptable)); //insertion d'image dans la fenetre pimage = gtk_image_new_from_file("img0.png"); pButton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(pButton1),pimage); gtk_table_attach(GTK_TABLE(ptable), pButton1,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0, 0); Block block = {0}; memset (&block, 0, sizeof(Block)); block.imge0 = (GtkImage*)gtk_image_new_from_file (g_strdup_printf ("img1.png",block.index)); g_free(block.imge0); block.imge1 = (GtkImage*)gtk_image_new_from_file (g_strdup_printf ("img1.png",block.index)); gtk_table_attach(GTK_TABLE(ptable), (GtkWidget*)block.imge0,2, 3, 0, 1,GTK_EXPAND,GTK_EXPAND,0, 0); gtk_table_attach(GTK_TABLE(ptable), (GtkWidget*)block.imge1,4, 5, 0, 1,GTK_EXPAND,GTK_EXPAND,0, 0); g_timeout_add(300,(GSourceFunc)show_image,&block); gtk_widget_show_all(Window); gtk_main(); return EXIT_SUCCESS; }
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