GTK中点击按钮打开新窗口并关闭旧窗口的实现问题
GTK4 切换窗口的实现方案
核心思路
点击按钮时,先创建并显示新窗口,再隐藏或销毁旧窗口。核心是要保证新窗口的事件循环能正常接管,不能在处理旧窗口时提前终止主循环。
完整代码示例
#include <gtk/gtk.h> // 创建新窗口的逻辑,参考官方示例结构 static void activate_new_window (GtkApplication *app) { GtkWidget *window; GtkWidget *button; GtkWidget *button_box; window = gtk_application_window_new (app); gtk_window_set_title (GTK_WINDOW (window), "New Window"); gtk_window_set_default_size (GTK_WINDOW (window), 200, 200); button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_window_set_child (GTK_WINDOW (window), button_box); button = gtk_button_new_with_label ("Close"); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window); gtk_box_append (GTK_BOX (button_box), button); gtk_widget_show (window); } // 按钮点击回调:执行窗口切换 static void on_new_window_clicked (GtkWidget *button, gpointer user_data) { GtkWidget *old_window = GTK_WIDGET(user_data); GtkApplication *app = gtk_window_get_application(GTK_WINDOW(old_window)); // 先创建并显示新窗口 activate_new_window(app); // 隐藏旧窗口,若无需再复用,可替换为 gtk_window_destroy(GTK_WINDOW(old_window)) gtk_widget_hide(old_window); } static void activate (GtkApplication *app, gpointer user_data) { GtkWidget *window; GtkWidget *button; GtkWidget *button_box; window = gtk_application_window_new (app); gtk_window_set_title (GTK_WINDOW (window), "Main Window"); gtk_window_set_default_size (GTK_WINDOW (window), 200, 200); button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL); gtk_window_set_child (GTK_WINDOW (window), button_box); button = gtk_button_new_with_label ("New Window"); // 将旧窗口作为参数传递给回调函数 g_signal_connect (button, "clicked", G_CALLBACK (on_new_window_clicked), window); gtk_box_append (GTK_BOX (button_box), button); gtk_widget_show (window); } int main (int argc, char **argv) { GtkApplication *app; int status; app = gtk_application_new ("org.example.SwitchWindow", G_APPLICATION_DEFAULT_FLAGS); g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); return status; }
关键注意事项
- 执行顺序:必须先完成新窗口的创建与显示,再处理旧窗口。如果先销毁旧窗口,可能导致应用主循环提前退出,新窗口无法正常启动。
- 应用上下文:通过
gtk_window_get_application获取同一应用实例,确保新窗口归属于当前应用的事件循环管理。 - 隐藏与销毁的选择:若之后需要重新打开旧窗口,用
gtk_widget_hide;若彻底不需要旧窗口,用gtk_window_destroy释放资源。
内容的提问来源于stack exchange,提问作者idk
相关产品推荐
相关产品推荐

