为什么子函数没有销毁GtkWindow?

问题描述 投票:0回答:1

这是我的代码。

 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。我期望通过点击 "enter_window2 "按钮来销毁window1。然而,当我运行这段代码时,事情并不像预期的那样。换句话说,当我按下按钮时,显示了window2,但window1没有被破坏。那么如何解决这个问题呢?

c gtk gtk3 gnome
1个回答
0
投票

你不需要嵌套的主循环,而且你也不应该使用它们:它们是一个反模式,而且GTK甚至不允许它们的存在(GTK 4正在移除 gtk_dialog_run() 甚至可能不会让你 "自己滚")。)

你可以也应该简单地使用信号来做这件事。你只需要把它们弄好。主要是:我们必须断开 ::destroy 处理人 window1 在我们将其销毁之前,作为切换到 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);
}

请注意,你不需要施法,以 GOBject* 对于 g_signal_connect() 或其他各种 "函数",其实就是为你检查这些的宏。

© www.soinside.com 2019 - 2024. All rights reserved.