首页 文章

C Gtk问题:在主窗口中添加VBox

提问于
浏览
3

我正在使用GTK库为界面编写C游戏 . 我们的想法是拥有两个主要容器:一个用于容纳按钮,另一个用于让用户选择设置,另一个用于在实际游戏过程中显示和移动图像 . 我正在使用VBox来保存菜单小部件,并使用固定容器来保存游戏精灵 . 我在这里有main()方法中与VBox和Fixed容器相关的所有代码行:

GtkWidget* vbox;
GtkWidget* fixed;
...
int main(int argc, char** argv) {
// (The rest of this code block is in the main method)
...
// Make a vertical box for the menu widgets.
vbox = gtk_vbox_new(TRUE, 0);

// Add the menu widgets to the vbox.
gtk_box_pack_start(GTK_BOX(vbox), label1, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 0);

// Make a new fixed container, which allows its children
// widgets to be moved dynamically.
fixed = gtk_fixed_new();

// Add the game widgets to the fixed container.
gtk_fixed_put(GTK_FIXED(fixed), player1, x, y);
gtk_fixed_put(GTK_FIXED(fixed), player2, x, y + 40);
gtk_fixed_put(GTK_FIXED(fixed), ball, x + 80, y);
gtk_fixed_put(GTK_FIXED(fixed), wall, x + 120, y);

// Add the fixed container to the window.
gtk_container_add(GTK_CONTAINER(window), vbox);

gtk_widget_show(vbox);
gtk_widget_show(fixed);

在我的一个按钮动作中,我有以下内容,以启动游戏玩法:

gtk_container_remove(GTK_CONTAINER(window), vbox);
gtk_container_add(GTK_CONTAINER(window), fixed);

哪个有效,没有任何问题 . 但是,在满足某个条件后,我会调用另一个函数,它执行相反的操作:

gtk_container_remove(GTK_CONTAINER(window), fixed);
gtk_container_add(GTK_CONTAINER(window), vbox);

这会导致以下问题:

(a.out:11762): Gtk-CRITICAL **: IA__gtk_container_add: assertion `GTK_IS_WIDGET (widget)' failed

我查看了小部件层次结构,并验证了VBox属于GtkWidget类别 . 当我最初将VBox添加到main()方法中的窗口时,没有发生上述错误 . 在调用gtk_main()之后将这个容器添加到窗口时,有什么我不知道的吗?

1 回答

  • 3

    问题是,GtkWidgets是引用计数,但您没有任何引用 . 这通常用于GtkWidgets,因为只要窗口小部件可见,窗口系统就会保存一个对它们的引用 . 但是只要从容器中删除小部件,引用计数就会降为零,并且会被销毁 .

    它第一次起作用是因为存在浮动引用,它就是在首次创建窗口小部件之后存在的 .

    最简单的解决方案就是保存对两个移动小部件的引用:在创建它们之后调用 g_object_ref_sink 将浮动引用转换为实际引用 . 但是当你完成它们时别忘了打电话给 g_object_unref

    其他选项只是在移动计数器时递增/递减计数器,但您仍需要将引用接收到 fixed 以按预期工作:

    g_object_ref_sink(fixed);
    

    然后:

    g_object_ref(vbox);
    gtk_container_remove(GTK_CONTAINER(window), vbox);
    gtk_container_add(GTK_CONTAINER(window), fixed);
    g_object_unref(fixed);
    

    和:

    g_object_ref(fixed);
    gtk_container_remove(GTK_CONTAINER(window), fixed);
    gtk_container_add(GTK_CONTAINER(window), vbox);
    g_object_unref(vbox);
    

相关问题