You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:22:38