【问题标题】:GTK+ Drawing_Area Image Redraw with Expose EventGTK+ Drawing_Area 使用 Expose 事件重绘图像
【发布时间】:2014-03-21 03:47:50
【问题描述】:

我有一个 C 语言程序,它基本上将图像读入 char 缓冲区,在将图像显示回屏幕之前对其像素执行一些操作。

到目前为止,图像显示正常;但我遇到了以下两个问题:

  1. 当我最小化 GTK 窗口并再次打开它时,图像就消失了,而 Drawing_Area 为空。
  2. 如何通过按下按钮重绘/更新 Drawing_Area 中的图像?

这是绘制的函数:

void Draw_Img(GtkWidget *widget, unsigned char **buffer,int x_offset,int y_offset,int x1, int y1,int x2, int y2)
{
  int i,j;
  int width,height;

  width=x2-x1+1;
  height=y2-y1+1;

  for(j=0;j<width*height;j++)
    tmp_buf[j]=0;

  for(j=y1;j<=y2;j++)
    for(i=x1;i<=x2;i++)
      tmp_buf[j*width+i-x1]=buffer[j][i];

  gdk_draw_gray_image(widget->window,
      widget->style->fg_gc[GTK_STATE_NORMAL], x_offset, y_offset,
     width, height, GDK_RGB_DITHER_NONE, tmp_buf, width);
}

主要功能:

int main(int argc,char **argv)
{
  gtk_init (&argc, &argv);    
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_window_set_title(GTK_WINDOW (window), "RESET DEMO");
  gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
  g_signal_connect (G_OBJECT (window), "destroy",
      G_CALLBACK (gtk_main_quit), NULL);

  button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
  g_signal_connect_swapped (button, "clicked", G_CALLBACK (display), drawing_area);

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), vbox);
  gtk_widget_show (vbox);

  gtk_widget_set_size_request(drawing_area, Test_Size*3, Test_Size);
  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
  gtk_widget_show(drawing_area);

  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
  gtk_widget_set_can_default (button, TRUE);
  gtk_widget_grab_default (button);
  gtk_widget_show (button);
  gtk_widget_show(window);

  /*
    reads image into buffer before calling the "display" function in which 
    calls the Draw_Img function
  */
  myinit();
  g_signal_connect (G_OBJECT (drawing_area), "expose_event",
       G_CALLBACK (display), NULL);

  gtk_main();
}

提前感谢您的任何帮助/意见。

【问题讨论】:

  • 是否有任何特殊原因阻止您使用cairo/Gtk+ 3.x/GtkDrawingArea for Gtk+3
  • 请问使用GTK+ 3和cairo有什么好处?我对此完全陌生。谢谢!
  • Gdk 绘图 foo 和Gtk+3.x 相比,cairo 设计得非常好(恕我直言)更少的错误,积极开发,更少的扭结和解决方法i> 绘图操作。至少这是我的个人经历。

标签: c events gtk redraw drawingarea


【解决方案1】:

gtk_widget_queue_draw 将重新排队要重绘的小部件。

最小化和取消最小化应该导致空白窗口,闻起来像您未提供的代码中的错误。

【讨论】:

  • 不确定是什么可能导致这个问题,我认为最小化窗口会导致窗口重绘本身,就像调整窗口大小一样......
  • 只发布更多代码,最好是重现错误的最小示例。
【解决方案2】:

我在这里找到了解决方案:http://blog.csdn.net/zhongguomin/article/details/7088575

调试两天后,我知道了。
注意:取消最小化会导致expose-event。

在 pixmap 上绘制 (pix,line,arc,rect,pixbuf) ,然后 queue_draw (将发出expose_event),在expose_event中放一个gdk_draw_drawable(pixmap)。

g_signal_connect (G_OBJECT (drawarea), "expose_event", G_CALLBACK (expose_event_callback), NULL);
gboolean expose_event_callback (GtkWidget * widget, GdkEventExpose * event, gpointer data)
{
  g_message ("expose_event");
  gdk_draw_drawable (widget->window, gc, pixmap, 0, 0, 0, 0, widget->allocation.width, widget->allocation.height);
  return TRUE;
}
......
gdk_draw_line (pixmap, gc, xa, ya, xb, yb);
gtk_widget_queue_draw (drawarea);
gdk_draw_rectangle (pixmap, gc, FALSE, x, y, w, h);
gtk_widget_queue_draw (drawarea);
gdk_draw_arc (pixmap, gc, FALSE, xb, ya, w, h, 0, 360 * 64);
gtk_widget_queue_draw (drawarea);
//image from file !!!
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (FCD));
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error);
gdk_draw_pixbuf (pixmap, gc, pixbuf, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
gtk_widget_queue_draw (drawarea);

但是我还有一个问题,当我尝试调整drawarea的大小时,像素图会崩溃。

然后我del if(pixmap)g_object_unref(pixmap);,crash就消失了,真是个大坑!

然后我制作一个新大小的新像素图,大小可以改变!

而allocation.width,allocation.height在queue_draw之前不生效,不能使用pixmap = gdk_pixmap_new(GDK_DRAWABLE(drawarea->window),widget->allocation.width,widget->allocation.height , -1); 现在!

int wpb = gdk_pixbuf_get_width (pixbuf);
int hpb = gdk_pixbuf_get_height (pixbuf);
g_message ("%d X %d", wpb, hpb);
gtk_widget_set_size_request(drawarea,wpb,hpb);    
pixmap = gdk_pixmap_new (GDK_DRAWABLE (drawarea->window),wpb,hpb, -1);
......

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多