destroy 和 delete-event

收到destroy信号后,GtkWidget会被销毁,但是gtk_main()循环还在继续,还需要调用gtk_main_quit()来结束循环。
destroy信号可以连接自定义的回调函数处理别的事情,但是不管怎么样,收到destroy信号以后,widget都会被销毁。
举个例子:
#include

void destroy(GtkObject *window, gpointer user_data)
{
g_print(“OH no no ~\n”);
}

int main(int argc, char *argv[])
{
GtkWidget *window;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

g_signal_connect(G_OBJECT(window), “destroy”, G_CALLBACK(destroy), NULL);

gtk_widget_show(window);

gtk_main();
}

这个程序在点击关闭以后,窗口被摧毁了,但是循环并没有退出。
换句话说,发出destroy信号后会销毁widget,除此以外什么也不干。假如需要在destroy的时候干点什么,给destroy连接一个回调函数。假如要destroy以后结束程序,在回调函数中加入gtk_main_quit()。
(BTW,销毁widget后的gtk_mian()似乎已经毫无意义了)。

用窗口管理器关闭widget会触发delete-event, delete-event的回调函数是有返回值的,如果返回TRUE,窗口管理器什么也不干;
如果返回FALSE,则发出destroy信号。假如对widget的destroy信号连接了回调函数,这个回调函数也会被执行。
(似乎没有给widget连接delete-event的话, 用窗口管理器关闭会直接触发destroy信号,我不太清楚其中的过程,不过就结果来看是这样的)
另一个问题:此时程序怎么判断给哪个widget发出destroy信号?与此有关的只有两个函数,g_signal_connect()和相应的回调函数的第一个参数。
从实例来看,似乎是按照g_signal_connect()中的第一个参数来决定的。
如下:

#include

gboolean destroy(GtkObject *window, GtkWidget *button)
{
gtk_main_quit();
return FALSE;
}

int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *button;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

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

button = gtk_button_new_with_label(“button”);
gtk_box_pack_start_defaults(GTK_BOX(vbox), button);

g_signal_connect_swapped(G_OBJECT(window), “destroy”, G_CALLBACK(destroy), (gpointer) button);

gtk_widget_show_all(window);

gtk_main();
}
这个程序正确的关闭了window而不是button。

gtk_widget_destroy(GtkWidget *widget)
似乎就是对参数中的widget发出destroy信号了。
注意:如果对widget的destroy信号连接了回调函数,在执行gtk_widget_destroy的时候,这个回调函数也会被执行。

updatedupdated2022-02-222022-02-22