modal dialog实现/ mainloop的嵌套/g_object_notify使用方法

转载自:

http://blog.csdn.net/hwizhao/archive/2009/02/10/3873577.aspx

 

modal dialog 的实现

 

gtk中,modal dialog的实现一般是说通过g_main_loop的嵌套来实现的。但最近发现并非如此。

是否为modal dialog, 主要由是否调用如下函数控制:

1、gtk_window_set_modal(window, TRUE);而这个函数主要做几件事情:

 (1)、向window manager设置_NET_WM_STATE atom中_NET_WM_STATE_MODAL 的值

 (2)、gtk_grab_add(window)

            gtk_grab_add(window)后,和这个window在一个group的窗口收到的点击事件等都不被处理

            当这个modal window 被hide或关掉后,再调用gtk_grab_remove(window)函数。

2、gtk_window_set_type_hint(window, GDK_WINDOW_TYPE_HINT_DIALOG);

      当设置了这个属性后,window manager将会将原来的窗口始终显示在点击出的窗口之下,即使之前的窗口已经获得了focus。

 

mainloop的嵌套

 

当已有了一个main loop在跑的情况下,在这个main loop的回调函数中可以new并run另一个main loop, 这时第一个main loop被block在执行这个回调函数中,而新生成的main loop由于和第一个main loop使用同一个context,将代替第一个main loop处理事件循环。

gboolean

shutdown_loop(GtkWidget *widget, GdkEventAny *evt, gpointer user_data)

{

       GMainLoop *loop = (GMainLoop *)user_data;

       if(g_main_loop_is_running(loop))

            g_main_loop_quit(loop);

      return FALSE;

}

g_boolean

show_modal_window(GtkWidget *widget, GdkEventButton *evt)

{

    ...

    GMainLoop *loop = g_main_loop_new(NULL, FALSE); // NULL ensures that this loop uses default context

   g_signal_connect(window, "delete_event", G_CALLBACK(shutdown_loop), loop);

   g_main_loop_run(loop);

   g_main_loop_unref(loop);

   return FALSE;

}

当一个dialog是否为modal,并不由其是否实现红色部分的代码(嵌套main loop)控制,而是由上面说过的两个函数决定的。

第二个loop的存在,使得即使在没有第一个loop的情况下,单独调用show_modal_window, 仍然可以处理消息循环。


g_object_notify的使用方法

 

0、注册部分

     g_object_class_install_property(gobject_class,

                                                        PROP_MODAL,

               g_param_spec_boolean("modal", P_("Modal"), P_("if true, the window is modal( other windows are not usable while this one is up)"),   FALSE, GTK_PARAM_READWRITE)

                                                       );

 

1、emit部分

     g_object_notify(G_OBJECT(window), "modal");

 

2.  connect部分

     g_signal_connect(window, "notify::modal", G_CALLBACK(notify_modal_received), NULL);

 

3、回调函数

     void notify_modal_received(GtkWidget *window, GParamSpec *pspec)

     {

         printf("notify modal received");

      }

 

4.调用顺序和运行结果:

1->2->3

notify modal received

 

5.g_object_notify作用描述:

提交一个“notify”信号给‘window‘对象的‘pspec‘属性

 

g_object_notify的另类使用

 

我们可以通过使用exo库提供的函数来进行多个对象中的属性关联

 

Thunar 1.0.0部分代码

thunar/thunar-preferences-dialog.c:

GtkWidget              *button;

  button = gtk_radio_button_new_with_mnemonic (NULL, _("_Object1"));
  exo_mutual_binding_new (G_OBJECT (dialog->preferences), "misc-single-click", G_OBJECT (button), "active");// 关联两个对象‘dialog->preferences’和‘button’的属性
  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (g_object_notify), "active");//radio button选中时发送notify给active
  gtk_table_attach (GTK_TABLE (table), button, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
  gtk_widget_show (button);

  button = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (button), _("_Object2"));
  exo_mutual_binding_new_with_negation (G_OBJECT (dialog->preferences), "misc-single-click", G_OBJECT (button), "active");
  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (g_object_notify), "active");
  gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
  gtk_widget_show (button);
 
关于控件绑定可以参考相关文章:

你可能感兴趣的:(.net,windows,Blog,UP)