0

我想用来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刷新(删除已绘制的内容)绘图区域并准备新的绘图。但它并没有删除已绘制的内容。为什么?如何刷新绘图区?

如果源文件是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 ();
}
4

0 回答 0