 |
GTK+ Forums Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
|
|
|
| Author |
Message |
|
|
roscarby Familiar Face
Joined: 27 Jun 2007 Posts: 5
|
Posted: Thu Jun 28, 2007 1:37 pm Post subject: Exposing a window during idle function execution |
|
|
I was trying to make a program
which draw lines requesting the end points
to the user via terminal, modifying scribble.c
I wrote the following code.
As you see the function draw_line is called
via g_idle_add. It happens that if I move a
whatever other window on the drawing area
while the draw_line function is waiting for me to insert
a new line, the lines and the drawing area deleted.
I would like to know what happens, and how to
avoid this.
This is my second day with gtk, so I would appreciate
also any other comment about the program and possible
hints.
Thanks in advance
Roscarby
| Code: (Plaintext) | 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
|
#include <gtk/gtk.h>
#include <glib/gstdio.h>
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event );
void quit_application(GtkWidget *w, gpointer user_data);
void on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
static GdkPixmap *pixmap = NULL;
GtkWidget *darea;
int dareaexist=0;
int main_start=0;
gboolean draw_line()
{
char c;
int x1,y1,x2,y2;
if(dareaexist>=0)
{
while(getchar()!='\n');
g_printf("Do you want to add a line (y/n) : ");
scanf("%c",&c);
if(c=='y')
{
g_printf("Insert 1st point x y: ");
scanf("%d %d",&x1,&y1);
g_printf("Insert 2nd point x y: ");
scanf("%d %d",&x2,&y2);
gdk_draw_line(darea->window,
darea->style->black_gc,
x1,y1,x2,y2
);
}
else
gtk_main_quit();
return TRUE;
};
}
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event )
{
if (pixmap)
g_object_unref (pixmap);
pixmap = gdk_pixmap_new (widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
gdk_draw_rectangle (pixmap,
widget->style->white_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
return TRUE;
}
static gboolean expose_event( GtkWidget *widget,
GdkEventExpose *event )
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
/* initialize the GTK+ library */
gtk_init (&argc, &argv);
/* create main window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Example");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_widget_set_size_request (window, 200, 100);
/* connect signals */
g_signal_connect (G_OBJECT(window), "destroy",
G_CALLBACK (quit_application), NULL);
g_signal_connect (G_OBJECT(window), "event-after",
G_CALLBACK (on_event_after), NULL);
gtk_widget_set_size_request(GTK_WIDGET(window),400,400);
gtk_widget_show (window);
g_idle_add(draw_line,NULL;
gtk_main ();
return 0;
}
void quit_application(GtkWidget *w, gpointer user_data)
{
gtk_main_quit();
}
void
on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
// g_printf("event type: %d \n",event->type);
if ((event->type == GDK_EXPOSE)&&(main_start==0))
{
char c;
g_printf("Do you want to create a drawing area: ");
scanf("%c",&c);
main_start = 1;
if (c=='y')
{
dareaexist=1;
darea = gtk_drawing_area_new();
gtk_widget_set_size_request(GTK_WIDGET(darea),400,400);
gtk_container_add (GTK_CONTAINER (widget), darea);
g_signal_connect (G_OBJECT (darea),"configure_event",
G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (darea), "expose_event",
G_CALLBACK (expose_event), NULL);
gtk_widget_show(darea);
}
}
}
| |
|
| Back to top |
|
 |
openldev Never Seen the Sunlight
Joined: 21 Sep 2005 Posts: 387 Location: Fairfax, Virginia
|
Posted: Thu Jun 28, 2007 7:35 pm Post subject: |
|
|
| The reason is because, every time an expose-event occurs, the widget is cleared. So, you must redraw your widget on expose-event. |
|
| Back to top |
|
 |
roscarby Familiar Face
Joined: 27 Jun 2007 Posts: 5
|
Posted: Mon Jul 02, 2007 2:53 pm Post subject: |
|
|
Well, it took me some time to get close to the solution,
but I think I am on the good way, I solved the problem by
using thread and not idle functions, the corrected code is
now:
| Code: (Plaintext) | 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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
|
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include <pthread.h>
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event );
void quit_application(GtkWidget *w, gpointer user_data);
void on_window_map (GtkWidget*, gpointer);
void on_window_realize (GtkWidget*, gpointer);
void on_window_show (GtkWidget*, gpointer);
static gboolean expose_event( GtkWidget *widget,
GdkEventExpose *event );
void
on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
static GdkPixmap *pixmap = NULL;
int dareaexist=0;
int main_start=0;
GtkWidget *window;
GtkWidget *darea;
void* draw_line(void* arg)
{
GdkEventExpose *event;
char c;
int x1,y1,x2,y2;
int h,w;
c='y';
do
{
if(dareaexist>0)
{
while(getchar()!='\n');
g_printf("Do you want to add a line (y/n) : ");
scanf("%c",&c);
if(c=='y')
{
g_printf("Insert 1st point x y: ");
scanf("%d %d",&x1,&y1);
g_printf("Insert 2nd point x y: ");
scanf("%d %d",&x2,&y2);
gdk_threads_enter();
gdk_draw_line(pixmap,
darea->style->black_gc,
x1,y1,x2,y2
);
gdk_window_get_size(pixmap, &w, &h);
gdk_draw_pixmap(darea->window,
darea->style->fg_gc[GTK_WIDGET_STATE (darea)],
pixmap,
0,
0,
0,
0,
w,
h );
gtk_widget_queue_draw (darea);
gdk_threads_leave();
};
};
}while(c!='n');
gtk_main_quit();
}
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event )
{
if (pixmap)
g_object_unref (pixmap);
pixmap = gdk_pixmap_new (widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
gdk_draw_rectangle (pixmap,
widget->style->white_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
return TRUE;
}
static gboolean expose_event( GtkWidget *widget,
GdkEventExpose *event )
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
int
main (int argc, char *argv[])
{
pthread_t tid;
/* initialize the GTK+ library */
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init (&argc, &argv);
/* create main window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Example");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_widget_set_size_request (window, 200, 100);
g_signal_connect (G_OBJECT(window), "event-after",
G_CALLBACK (on_event_after), NULL);
gtk_widget_set_size_request(GTK_WIDGET(window),400,400);
gtk_widget_show (window);
pthread_create(&tid,NULL,draw_line,NULL);
gtk_main ();
gdk_threads_leave();
return 0;
}
void quit_application(GtkWidget *w, gpointer user_data)
{
gtk_main_quit();
}
void
on_window_map (GtkWidget *w,gpointer user_data)
{
g_print("Window was mapped.\n");
}
void
on_window_realize (GtkWidget *w,gpointer user_data)
{
g_print("Window was realized.\n");
}
void
on_window_show (GtkWidget *w,gpointer user_data)
{
g_print("Window was shown.\n");
}
void
on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
// g_printf("event type: %d \n",event->type);
if ((event->type == GDK_EXPOSE)&&(main_start==0))
{
char c;
g_printf("Do you want to create a drawing area: ");
scanf("%c",&c);
main_start = 1;
if (c=='y')
{
dareaexist=1;
darea = gtk_drawing_area_new();
gtk_widget_set_size_request(GTK_WIDGET(darea),400,400);
gtk_container_add (GTK_CONTAINER (widget), darea);
g_signal_connect (G_OBJECT (darea),"configure_event",
G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (darea), "expose_event",
G_CALLBACK (expose_event), NULL);
gtk_widget_show(darea);
}
}
}
|
to be compiled with `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
I would like to have opinions about the solution particularly is it correct?
Could I do the same without using threads?
Hints about possible improvements.. i am just learning gtk+ and c together so any advice would be welcome.
Thanx a lot
roscarby |
|
| Back to top |
|
 |
|
Powered by phpBB © 2001, 2005 phpBB Group CodeBB 1.0 Beta 2
|