GTK+ How to draw into a drawing area

12,582

All your drawing should happen in the drawing area drawing event, called expose-event for GTK2 and draw in GTK3. In response to the button being clicked, you just change some values that you will reuse to compute the whole scene drawn. Once you changed these values, you just invalidate the drawing area to force it being redrawn, calling gtk_widget_queue_draw on the drawing area. And that's it.

If the scene is expensive to draw, remember using cairo clipping functions to improve performance by drawing only what has changed. Use then gtk_widget_queue_draw_area instead of gtk_widget_queue_draw, to give a hint about the zone that has changed and needs to be redrawn.

See GtkDrawingArea documentation.

BTW, don't use casts to GTK_OBJECT (deprecated), use G_OBJECT instead. This makes porting to GTK3 easier.

Share:
12,582

Related videos on Youtube

STiLLeN
Author by

STiLLeN

Updated on June 04, 2022

Comments

  • STiLLeN
    STiLLeN almost 2 years

    I would like to draw some lines (actually a sine wave) inside a gtk+ cairo drawing area but I can't figure out a way to do that. So my code first defines the drawing area which has a callback to a function that draws a white background into the drawing area itself...at this point I would like to start drawing a piece of the sin wave after each time the START button is pressed (the button has a callback to the drawing function).... So first of all..would it be possible to do that??Am I missing something? Thanks.

        #include <cairo.h>
        #include <gtk/gtk.h>
    
        int x = 0;
        int x_old = 0;
        float value = 0;
        float value_old = 0;
        GtkWidget *button = NULL;
        GtkWidget *window = NULL;
        GtkWidget *area = NULL;
        GtkWidget *table = NULL;
    
        static gboolean load_interface(GtkWidget *widget)
        {
         cairo_t *cr;
         cr = gdk_cairo_create(area->window);
         cairo_set_source_rgb(cr, 1, 1, 1);
         cairo_rectangle(cr, 0, 0, 900, 400);
         cairo_fill(cr);
        }
    
        void draw(GtkWidget *widget)
        {
         cairo_t *cr;
         cr = gdk_cairo_create(widget->window);
    
         x_old = x;
         x = x + 15;
         value_old = value;
         value = value + 0.25;
    
         cairo_set_source_rgb(cr, 0, 0, 0);
         cairo_set_line_width (cr, 1);
         cairo_move_to(cr, x_old, 100 + (sin(value_old))*50);
         cairo_line_to(cr, x, 100 + (sin(value))*50);
         cairo_stroke(cr);
        }
    
    
         int main (int argc, char *argv[])
        {
          g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
          gtk_init (&argc, &argv);
          g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);
    
          window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
          gtk_container_set_border_width (GTK_CONTAINER (window), 3);
          gtk_window_set_title (GTK_WINDOW (window), "Draw");
          gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
          gtk_widget_realize (window);
          g_signal_connect (window, "destroy", gtk_main_quit, NULL);
    
          table = gtk_table_new (10, 10, TRUE);
          gtk_table_set_col_spacings(GTK_TABLE(table),10);
          gtk_table_set_row_spacings(GTK_TABLE(table),5);
          gtk_container_add (GTK_CONTAINER (window), table);
    
          area = gtk_drawing_area_new();
          gtk_signal_connect (GTK_OBJECT(area), "event", G_CALLBACK (load_interface),     (gpointer)area);
          gtk_table_attach_defaults (GTK_TABLE(table), area, 1, 10, 0, 10);
    
          button = gtk_button_new_from_stock ("START");
          g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (draw), (gpointer) window);
          gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 1, 0, 1);
    
          gtk_widget_show_all (window);
          gtk_main ();
    
          return 0;
         }
    
    • liberforce
      liberforce over 11 years
      Are you using GTK2 or GTK3? Looks it's GTK2, but I'm not sure.
    • STiLLeN
      STiLLeN over 11 years
      yes I'm using GTK2 on windows...