gtk绘制“expose-event”并重绘

时间:2012-07-06 10:15:13

标签: gtk redraw

我想使用expose-event绘制内容然后更新或重绘。也就是说,窗口中有一个绘图区域和一个按钮。单击按钮时,将相应地重绘绘图区域。我的问题是

  1. 在以下代码中,如果我将gtk_container_add (GTK_CONTAINER (box), canvas);更改为gtk_box_pack_start(GTK_BOX(box), canvas, FALSE, FALSE, 0);,则不会绘制任何内容。通常我们使用gtk_box_pack_start在框中添加内容。这次为什么不起作用?

  2. 功能build_ACC_axis刷新(删除已绘制的)绘图区域并为新绘制做好准备。但它没有删除所绘制的内容。为什么?如何刷新绘图区域?

  3. 如果源文件是test.c,则编译为

      

    gcc -o test test.c`pkg-config --cflags --libs gtk + -2.0`

    代码如下:

    #include <gtk/gtk.h>
    #include <glib.h>
    
    static void draw (GdkDrawable *d, GdkGC *gc)
    {
      /* Draw with GDK */
      gdk_draw_line (d, gc, 0, 0, 50, 50);
      gdk_draw_line (d, gc, 50, 50, 50, 150);
      gdk_draw_line (d, gc, 50, 150, 0, 200);
    
      gdk_draw_line (d, gc, 200, 0, 150, 50);
      gdk_draw_line (d, gc, 150, 50, 150, 150);
      gdk_draw_line (d, gc, 150, 150, 200, 200);
    
      gdk_draw_line (d, gc, 50, 50, 150, 50);
      gdk_draw_line (d, gc, 50, 150, 150, 150);
    }
    
    static gboolean expose_cb (GtkWidget *canvas, GdkEventExpose *event, gpointer user_data)
    {
      GdkGC *gc;
    
      gc = gdk_gc_new (canvas->window);
      draw (canvas->window, gc);
      g_object_unref (gc);
    
      return FALSE;
    }
    
    void build_ACC_axis (GtkWidget *button, GtkWidget *widget)
    {
      GdkRegion *region;
    
      GtkWidget *canvas = g_object_get_data(G_OBJECT(widget), "plat_GA_canvas");
    
      region = gdk_drawable_get_visible_region(canvas->window);
      gdk_window_invalidate_region(canvas->window, region, TRUE);
      gtk_widget_queue_draw(canvas);
      /* gdk_window_process_updates(canvas->window, TRUE); */
      gdk_region_destroy (region);
    }
    
    int main (int argc, char **argv)
    {
      GtkWidget *window;
      GtkWidget *canvas, *box, *button;
    
      gtk_init (&argc, &argv);
    
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request(window, 500, 300);
      g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
    
      box = gtk_vbox_new(FALSE, 0);
      gtk_container_add (GTK_CONTAINER (window), box);
    
      canvas = gtk_drawing_area_new ();
      g_object_set_data(G_OBJECT(window), "plat_GA_canvas", canvas);
      /* gtk_box_pack_start(GTK_BOX(box), canvas, FALSE, FALSE, 0); */
      gtk_container_add (GTK_CONTAINER (box), canvas);
      g_signal_connect (G_OBJECT (canvas), "expose-event", G_CALLBACK (expose_cb), NULL);
    
      button = gtk_button_new_with_label ("ok");
      gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
      /* gtk_container_add (GTK_CONTAINER (box), button); */
      gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(build_ACC_axis), window);
    
      gtk_widget_show_all (window);
    
      gtk_main ();
    }
    

    我想回答我的第二个问题。点击按钮后,它会发送expose-event信号并运行expose_cb。由于draw功能没有变化,我们无法看清楚。以下是可以显示刷新的更新代码。重点是添加变量factor。但对于第一个问题,我仍然不知道为什么。

    #include <gtk/gtk.h>
    #include <glib.h>
    
    int factor;
    static void draw (GdkDrawable *d, GdkGC *gc, double fac)
    {
      /* Draw with GDK */
      gdk_draw_line (d, gc, 0, 0, 50, 50 * fac);
      gdk_draw_line (d, gc, 50, 50, 50, 150);
      gdk_draw_line (d, gc, 50, 150, 0, 200);
    
      gdk_draw_line (d, gc, 200, 0, 150, 50);
      gdk_draw_line (d, gc, 150, 50, 150, 150);
      gdk_draw_line (d, gc, 150, 150, 200, 200);
    
      gdk_draw_line (d, gc, 50, 50, 150, 50);
      gdk_draw_line (d, gc, 50, 150, 150, 150);
    }
    
    static gboolean expose_cb (GtkWidget *canvas, GdkEventExpose *event, gpointer user_data)
    {
      GdkGC *gc;
    
      gc = gdk_gc_new (canvas->window);
      draw (canvas->window, gc, factor);
      g_object_unref (gc);
    
      return FALSE;
    }
    
    void build_ACC_axis (GtkWidget *button, GtkWidget *widget)
    {
      GdkRegion *region;
    
      GtkWidget *canvas = g_object_get_data(G_OBJECT(widget), "plat_GA_canvas");
    
      region = gdk_drawable_get_visible_region(canvas->window);
      gdk_window_invalidate_region(canvas->window, region, TRUE);
      /* gtk_widget_queue_draw(canvas); */
      gdk_window_process_updates(canvas->window, TRUE);
      gdk_region_destroy (region);
      factor++;
    
    }
    
    int main (int argc, char **argv)
    {
      GtkWidget *window;
      GtkWidget *canvas, *box, *button;
    
      gtk_init (&argc, &argv);
    
      factor = 1;
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_set_size_request(window, 500, 300);
      g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
    
      box = gtk_vbox_new(FALSE, 0);
      gtk_container_add (GTK_CONTAINER (window), box);
    
      canvas = gtk_drawing_area_new ();
      g_object_set_data(G_OBJECT(window), "plat_GA_canvas", canvas);
      /* gtk_box_pack_start(GTK_BOX(box), canvas, FALSE, FALSE, 0); */
      gtk_container_add (GTK_CONTAINER (box), canvas);
      g_signal_connect (G_OBJECT (canvas), "expose-event", G_CALLBACK (expose_cb), NULL);
    
      button = gtk_button_new_with_label ("ok");
      gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
      /* gtk_container_add (GTK_CONTAINER (box), button); */
      gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(build_ACC_axis), window);
    
      gtk_widget_show_all (window);
    
      gtk_main ();
    }
    

0 个答案:

没有答案