GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Jul 25, 2014 3:58 pm

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Exposing a window during idle function execution
PostPosted: Thu Jun 28, 2007 1:37 pm 
Offline
Familiar Face

Joined: Wed Jun 27, 2007 11:45 am
Posts: 5
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:

#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);
   
   }


   }
}



Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 28, 2007 7:35 pm 
Offline
Never Seen the Sunlight

Joined: Wed Sep 21, 2005 3:07 am
Posts: 384
Location: Fairfax, Virginia
The reason is because, every time an expose-event occurs, the widget is cleared. So, you must redraw your widget on expose-event.

_________________
Andrew Krause

Foundations of GTK+ Development: Buy now for only $31.49!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 02, 2007 2:53 pm 
Offline
Familiar Face

Joined: Wed Jun 27, 2007 11:45 am
Posts: 5
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:

#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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group