为什么子函数不破坏 GtkWindow?
Why does the subfunction not destroy the GtkWindow?
这是我的代码:
void window_first();
void enter_window2(GtkWidget* w, gpointer data);
void quit(GtkWidget* w, gpointer data);
void quit();
int main(int argc, char* argv[])
{
GtkWidget* window2;
gtk_init(&argc, &argv);
window_first();
window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show_all(window2);
g_signal_connect(G_OBJECT(window2), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
void quit(GtkWidget* w, gpointer data)
{
exit(1);
}
void enter_window2(GtkWidget* w, gpointer data)
{
gtk_main_quit();
}
void window_first()
{
GtkWidget* window1, *vbox, *enter_window2_button;
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
enter_window2_button = gtk_button_new_with_label("enter_window2");
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start(GTK_BOX(vbox),enter_window2_button, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window1), vbox);
g_signal_connect(G_OBJECT(window1), "destroy", G_CALLBACK(quit), NULL);
g_signal_connect(G_OBJECT(enter_window2_button), "clicked", G_CALLBACK(enter_window2), NULL);
gtk_widget_show_all(window1);
gtk_main();
return;
}
我的代码的目的是首先构建一个名为 "window1" 的 GtkWindow,它有一个名为 enter_window2 的 GtkButton,然后在 window1 被销毁后构建另一个名为 "window2" 的 GtkWindow。我希望 window1 通过单击 "enter_window2" 按钮被销毁。但是,当我运行代码。事情不如预期。换句话说,当我按下按钮时,会显示 window2,但 window1 不会被销毁。那么如何解决呢?
为此您不需要嵌套的主循环,而且您无论如何也不应该使用它们:它们是一种反模式,GTK 正在远离甚至允许它们(GTK 4 正在删除 gtk_dialog_run()
甚至可能不会让你 'roll your own').
您可以而且应该简单地使用信号来做到这一点。你只需要让他们正确。主要是:我们必须在 window1
上断开 ::destroy
处理程序,然后再销毁它作为切换到 window2
的一部分。否则,很简单:
#include <gtk/gtk.h>
void window_first();
void enter_window2(GtkWidget* w, gpointer data);
void window_second();
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
window_first();
gtk_main();
return 0;
}
void enter_window2(GtkWidget* w, gpointer data)
{
GtkWindow *window1 = GTK_WINDOW(data);
g_signal_handlers_disconnect_by_func(window1, gtk_main_quit, NULL);
gtk_widget_destroy(GTK_WIDGET(window1));
window_second();
}
void window_first()
{
GtkWidget *window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *enter_window2_button = gtk_button_new_with_label("enter_window2");
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start(GTK_BOX(vbox),enter_window2_button, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window1), vbox);
g_signal_connect(window1, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(enter_window2_button, "clicked", G_CALLBACK(enter_window2), window1);
gtk_widget_show_all(window1);
}
void window_second()
{
GtkWidget *window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show_all(window2);
g_signal_connect(window2, "destroy", G_CALLBACK(gtk_main_quit), NULL);
}
请注意,对于 g_signal_connect()
或其他各种 'functions',您不需要强制转换为 GOBject*
,它们实际上是为您检查的宏。
这是我的代码:
void window_first();
void enter_window2(GtkWidget* w, gpointer data);
void quit(GtkWidget* w, gpointer data);
void quit();
int main(int argc, char* argv[])
{
GtkWidget* window2;
gtk_init(&argc, &argv);
window_first();
window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show_all(window2);
g_signal_connect(G_OBJECT(window2), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
void quit(GtkWidget* w, gpointer data)
{
exit(1);
}
void enter_window2(GtkWidget* w, gpointer data)
{
gtk_main_quit();
}
void window_first()
{
GtkWidget* window1, *vbox, *enter_window2_button;
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
enter_window2_button = gtk_button_new_with_label("enter_window2");
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start(GTK_BOX(vbox),enter_window2_button, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window1), vbox);
g_signal_connect(G_OBJECT(window1), "destroy", G_CALLBACK(quit), NULL);
g_signal_connect(G_OBJECT(enter_window2_button), "clicked", G_CALLBACK(enter_window2), NULL);
gtk_widget_show_all(window1);
gtk_main();
return;
}
我的代码的目的是首先构建一个名为 "window1" 的 GtkWindow,它有一个名为 enter_window2 的 GtkButton,然后在 window1 被销毁后构建另一个名为 "window2" 的 GtkWindow。我希望 window1 通过单击 "enter_window2" 按钮被销毁。但是,当我运行代码。事情不如预期。换句话说,当我按下按钮时,会显示 window2,但 window1 不会被销毁。那么如何解决呢?
为此您不需要嵌套的主循环,而且您无论如何也不应该使用它们:它们是一种反模式,GTK 正在远离甚至允许它们(GTK 4 正在删除 gtk_dialog_run()
甚至可能不会让你 'roll your own').
您可以而且应该简单地使用信号来做到这一点。你只需要让他们正确。主要是:我们必须在 window1
上断开 ::destroy
处理程序,然后再销毁它作为切换到 window2
的一部分。否则,很简单:
#include <gtk/gtk.h>
void window_first();
void enter_window2(GtkWidget* w, gpointer data);
void window_second();
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
window_first();
gtk_main();
return 0;
}
void enter_window2(GtkWidget* w, gpointer data)
{
GtkWindow *window1 = GTK_WINDOW(data);
g_signal_handlers_disconnect_by_func(window1, gtk_main_quit, NULL);
gtk_widget_destroy(GTK_WIDGET(window1));
window_second();
}
void window_first()
{
GtkWidget *window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *enter_window2_button = gtk_button_new_with_label("enter_window2");
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start(GTK_BOX(vbox),enter_window2_button, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(window1), vbox);
g_signal_connect(window1, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(enter_window2_button, "clicked", G_CALLBACK(enter_window2), window1);
gtk_widget_show_all(window1);
}
void window_second()
{
GtkWidget *window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show_all(window2);
g_signal_connect(window2, "destroy", G_CALLBACK(gtk_main_quit), NULL);
}
请注意,对于 g_signal_connect()
或其他各种 'functions',您不需要强制转换为 GOBject*
,它们实际上是为您检查的宏。