Canvas gtk+;:如何立即刷新画布(已关闭)

Canvas gtk+;:如何立即刷新画布(已关闭),canvas,gtk,refresh,Canvas,Gtk,Refresh,接下来是gtk+中的布局 +----------------------------+------+------+------+ | |Page 1|Page 2|Page 3| | +------+------+------+ | | | |

接下来是
gtk+
中的布局

+----------------------------+------+------+------+
|                            |Page 1|Page 2|Page 3|
|                            +------+------+------+
|                            |                    |
|                            |                    |
|     Canvas area            |                    |
|                            |                    |
|                            |                    |
|                            |                    |
|                            |                    |
|                            |                    |
+------------------+---------+                    |
|                  | button  |                    |
|                  +---------+                    |
|                            |                    |
|                            |                    |
|                            |                    |
|                            |                    |
+----------------------------+--------------------+
->左侧的“画布区域”和“按钮”位于垂直框中。右边的“第1~3页”是另一个垂直框中的笔记本页面

->左侧的“画布区域”由
gtk\u drawing\u area\u new
创建,并与信号
expose event
连接

->在“第3页”中,有一个“画布区域”,其创建方式与上面类似

->每次按下“按钮”,左侧的“画布区域”都会立即刷新

问题是

->如果第3页是当前的页,当按下“按钮”时,第3页中的“画布区域”将不会刷新,直到我切换到另一页,例如第1页或第2页,然后切换回第3页。如果始终停留在“第3页”,则似乎不会发出信号
expose event

->当第3页是当前的
页面时,是否可以刷新第3页中的“画布区域”,就像左侧的“画布区域”在按下“按钮”时立即刷新一样

->我曾经尝试过
gdk\u threads\u enter
gdk\u threads\u leave
,但都没用

请帮忙。多谢各位


下面是一个小例子。它运行良好,我的意思是上面提到的问题不会出现。问题出在“按钮按下”功能中,我在应用程序中遗漏了“gdk\U无效区域(g\U对象\U获取数据(g\U对象(小部件),“右画布”);”。

#include <gtk/gtk.h>

int num, if_draw = 0;

void gdk_invalidate_region (GtkWidget *obj)
{
  GdkRegion *region;

  region = gdk_drawable_get_visible_region(obj->window);
  gdk_window_invalidate_region(obj->window, region, TRUE);
  gdk_region_destroy (region);
  gtk_widget_queue_draw(obj);
  /* gdk_window_process_updates(obj->window, TRUE); */
}

void num_changed (GtkWidget *box, GtkWidget *window)
{
  num = gtk_option_menu_get_history((GtkOptionMenu *)box) + 1;
  if_draw = 0;
  gdk_invalidate_region (g_object_get_data(G_OBJECT(window), "left_canvas"));
  gdk_invalidate_region (g_object_get_data(G_OBJECT(window), "right_canvas"));
}

gboolean draw_expose_left (GtkWidget *canvas, GdkEventExpose *event, gpointer user_data)
{
  cairo_t *cr;

  cr = gdk_cairo_create (canvas->window);
  if(if_draw)
  {
    int i;

    cairo_set_line_width (cr, 0.7);
    for(i = 0; i < num; i++)
    {
      printf("i=%d\n", i);
      cairo_move_to(cr, 50, (i + 1) * 50);
      cairo_rel_line_to(cr, 150, 0);
      cairo_stroke(cr);
    }
  }
  else
  {
    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size(cr, 0.35);
    cairo_move_to(cr, 5, canvas->allocation.height / 2);
    cairo_show_text(cr, "Press button \"Press..\" to update!!");
  }
  cairo_destroy (cr);

  return FALSE;
}

gboolean draw_expose_right (GtkWidget *canvas, GdkEventExpose *event, gpointer user_data)
{
  cairo_t *cr;

  cr = gdk_cairo_create (canvas->window);
  if(if_draw)
  {
    int i;

    cairo_set_line_width (cr, 0.7);
    for(i = 0; i < num; i++)
    {
      printf("i=%d\n", i);
      cairo_move_to(cr, (i + 1) * 50, 50);
      cairo_rel_line_to(cr, 0, 100);
      cairo_stroke(cr);
    }
  }
  else
  {
    cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size(cr, 0.35);
    cairo_move_to(cr, 5, canvas->allocation.height / 2);
    cairo_show_text(cr, "Press button \"Press..\" to update!!");
  }
  cairo_destroy (cr);

  return FALSE;
}

void button_pressed (GtkWidget *button, GtkWidget *widget)
{
  gdk_invalidate_region (g_object_get_data(G_OBJECT(widget), "left_canvas"));
  gdk_invalidate_region (g_object_get_data(G_OBJECT(widget), "right_canvas"));
  if_draw = 1;
}

int main (int argc, char *argv[])
{
  GtkWidget *window, *main_box, *box, *hbox, *entry, *menu, *menu_item;
  GtkWidget *notebook, *label;

  gtk_init(&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  /* gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); */
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

  main_box = gtk_hbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(window), main_box);
  gtk_widget_show(main_box);

  /***** left **********/
  box = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_box), box, FALSE, TRUE, 0);
  gtk_widget_show(box);

  entry = gtk_drawing_area_new();
  gtk_widget_set_size_request(entry, 400, 200);
  g_object_set_data(G_OBJECT(window), "left_canvas", entry);
  gtk_widget_show(entry);
  gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
  g_signal_connect(G_OBJECT(entry), "expose-event", G_CALLBACK(draw_expose_left), window);

  hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, TRUE, 0);
  gtk_widget_show(hbox);

  entry = gtk_label_new("Num: ");
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  gtk_widget_show(entry);

  entry = gtk_option_menu_new();
  gtk_widget_set_size_request(entry, 40, -1);
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  gtk_widget_show(entry);

  menu = gtk_menu_new();
  menu_item = gtk_menu_item_new_with_label("1");
  gtk_widget_show(menu_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
  menu_item = gtk_menu_item_new_with_label("2");
  gtk_widget_show(menu_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
  menu_item = gtk_menu_item_new_with_label("3");
  gtk_widget_show(menu_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
  gtk_option_menu_set_menu(GTK_OPTION_MENU(entry), menu);
  gtk_option_menu_set_history((GtkOptionMenu *)entry, 1);
  num = 2;
  gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(num_changed), window);

  entry = gtk_button_new_with_label("Press..");
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  gtk_signal_connect(GTK_OBJECT(entry), "clicked", GTK_SIGNAL_FUNC(button_pressed), window);
  gtk_widget_show(entry);
  /*********************/

  /***** right *********/
  box = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(main_box), box, FALSE, TRUE, 0);
  gtk_widget_show(box);

  notebook = gtk_notebook_new();
  gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
  gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
  /* g_signal_connect(G_OBJECT(notebook), "switch-page", G_CALLBACK(qqaa_show_page_status_ACC_platform), window); */
  gtk_widget_show(notebook);

  entry = gtk_label_new("ONE");
  label = gtk_label_new("Page 1");
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), entry, label);

  entry = gtk_label_new("TWO");
  label = gtk_label_new("Page 2");
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), entry, label);

  entry = gtk_drawing_area_new();
  gtk_widget_set_size_request(entry, 400, 200);
  g_object_set_data(G_OBJECT(window), "right_canvas", entry);
  gtk_widget_show(entry);
  g_signal_connect(G_OBJECT(entry), "expose-event", G_CALLBACK(draw_expose_right), window);
  label = gtk_label_new("Page 3");
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), entry, label);
  /*********************/

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}
#包括
int num,如果_draw=0;
无效gdk_无效_区域(GtkWidget*obj)
{
格德克利翁*地区;
region=gdk\u可绘制\u获取\u可见\u区域(obj->window);
gdk_窗口_失效_区域(obj->window,region,TRUE);
gdk_区域_销毁(区域);
gtk_小部件_队列_绘制(obj);
/*gdk_窗口_进程_更新(obj->window,TRUE)*/
}
void num_已更改(GtkWidget*框、GtkWidget*窗口)
{
num=gtk_选项_菜单_获取_历史((gtk选项菜单*)框)+1;
如果_draw=0;
gdk_无效_区域(g_对象_获取_数据(g_对象(窗口),“左_画布”);
gdk_无效_区域(g_对象_获取_数据(g_对象(窗口),“右_画布”);
}
gboolean draw_expose_left(GtkWidget*画布、GdkEventExpose*事件、gpointer用户数据)
{
开罗*cr;
cr=gdk\u cairo\u create(画布->窗口);
if(if_draw)
{
int i;
cairo\u set\u line\u width(cr,0.7);
对于(i=0;iallocation.height/2);
cairo_show_text(cr,“按按钮”“按..”“更新!!”);
}
开罗大学(cr);
返回FALSE;
}
gboolean绘图右曝光(GtkWidget*画布、GdkEventExpose*事件、gpointer用户数据)
{
开罗*cr;
cr=gdk\u cairo\u create(画布->窗口);
if(if_draw)
{
int i;
cairo\u set\u line\u width(cr,0.7);
对于(i=0;iallocation.height/2);
cairo_show_text(cr,“按按钮”“按..”“更新!!”);
}
开罗大学(cr);
返回FALSE;
}
按下无效按钮(GtkWidget*按钮,GtkWidget*小部件)
{
gdk_无效_区域(g_对象_获取_数据(g_对象(小部件),“左_画布”);
gdk_无效_区域(g_对象_获取_数据(g_对象(小部件),“右_画布”);
如果_draw=1;
}
int main(int argc,char*argv[])
{
GtkWidget*窗口、*主框、*框、*hbox、*条目、*菜单、*菜单项;
GtkWidget*笔记本,*标签;
gtk_init(&argc,&argv);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
/*gtk_窗口设置默认大小(gtk_窗口(窗口),300,200)*/
g_信号连接(g_对象(窗口),“销毁”,g_回调(gtk_主退出),NULL);
主框=gtk\U hbox\U新(假,0);
gtk_容器添加(gtk_容器(窗口),主盒);
gtk_小部件_显示(主_框);
/*****左**********/
框=gtk_vbox_新(假,0);
gtk_-box_-pack_-start(gtk_-box(主_-box)),box,FALSE,TRUE,0;
gtk_widget_show(框);
条目=gtk_图纸_区域_新();
gtk_小部件_设置_大小_请求(条目,400200);
g_对象_集合_数据(g_对象(窗口),“左画布”,条目);
gtk_widget_show(条目);
gtk_-box_-pack_-start(gtk_-box(box)),输入,真,真,0;
g_信号_连接(g_对象(条目),“暴露事件”,g_回调(左绘制),窗口);
hbox=gtk_hbox_new(假,0);
gtk_-box_-pack_启动(gtk_-box(box),hbox,假,真,0);
gtk_widget_show(hbox);
条目=gtk_标签_新(“编号:”);
gtk_-box_-pack_-start(gtk_-box(hbox)),输入,真,真,0;
gtk_widget_show(条目);
entry=gtk_选项_菜单_新建();
gtk_小部件_设置_大小_请求(条目,40,-1);
gtk_-box_-pack_-start(gtk_-box(hbox)),输入,真,真,0;
gtk_widget_show(条目);
menu=gtk_menu_new();
菜单项=gtk菜单项带标签的新菜单项(“1”);
gtk_小部件_显示(菜单项);
gtk_菜单_外壳_附加(gtk_菜单_外壳(菜单),菜单项);
菜单项=gtk菜单项带标签的新菜单项(“2”);
gtk_小部件_显示(菜单项);
gtk_菜单_外壳_附加(gtk_菜单_外壳(菜单),菜单项);
菜单项=gtk菜单项带有标签(“3”);
gtk_小部件_显示(菜单项);
gtk_菜单_外壳_附加(gtk_菜单_外壳(菜单),菜单项);
gtk_选项菜单设置菜单(gtk_选项菜单(条目),菜单);
gtk_选项_菜单_设置_历史((gtk选项菜单*)条目,1);
num=2;
gtk_信号连接(gtk_对象(条目),“已更改”,gtk_信号功能(已更改数量),窗口);
输入=gtk_按钮_新建_,带有标签(“按下”);
gtk_-box_-pack_-start(gtk_-box(hbox)),输入,真,真,0;
gtk_信号连接(gtk_对象(条目),“单击”,gtk_信号功能(按下按钮),窗口);
gtk_widget_show(条目);
/********