GTK3:gtk_widget_destroy与gtk_widget_hide

时间:2018-03-05 09:35:13

标签: c gtk3

这是一个简短的MCV来说明我遇到的问题:

我从主窗口调出一个对话框。 我点击对话框中的一个按钮(我认为通常的方式) 如果我再次单击一个按钮,对话框将不会再次显示(我收到了一堆错误)。 我没有使用gtk_widget_hide。 (接口是用Glade3设计的)

typedef struct {
    GtkBuilder *builder;
    gchar *stuff;
} Context;

void conDisplay(GtkWidget *g, gpointer userdata) {
    GtkWidget *dlg, *parent;
    Context *ctx=(Context *)userdata;
    int ret=0;

    g_printerr("clicked\n");

    parent=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"MCV"));
    if (ctx->stuff) {
        g_printerr("Already connected\n");
        dlg=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"question"));
        gtk_window_set_transient_for(GTK_WINDOW(dlg),GTK_WINDOW(parent));
        ret=gtk_dialog_run(dlg);
        if (ret==-3) { // OK clicked
            g_printerr("OK from Already connected\n");
        }
        else { g_printerr("Unknown\n"); }
        gtk_window_set_transient_for(GTK_WINDOW(dlg),NULL);
        gtk_widget_destroy(GTK_WIDGET(dlg));
    } else {
        dlg=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"connect"));
        gtk_window_set_transient_for(GTK_WINDOW(dlg),GTK_WINDOW(parent));
        ret=gtk_dialog_run(dlg);
        if (ret==-1) { // GO clicked
            g_printerr("GO\n");
            ctx->stuff="Hello";
        }
        else { g_printerr("Cancel\n"); }
        gtk_window_set_transient_for(GTK_WINDOW(dlg),NULL);
        gtk_widget_destroy(GTK_WIDGET(dlg));
    }
}

int main(int argc, char **argv)
{
    Context ctx;
    GtkWidget *mainwin;
    GtkWidget *btnCon;
    GError *error=NULL;

    /* Init GTK+ */
    gtk_init(&argc,&argv);
    ctx.builder=gtk_builder_new();
    ctx.stuff=NULL;
    // Load UI from file.
    gtk_builder_add_from_file(ctx.builder,"mcv.glade",&error);

    mainwin=GTK_WIDGET(gtk_builder_get_object(ctx.builder,(gchar *)"MCV"));
    btnCon=GTK_WIDGET(gtk_builder_get_object(ctx.builder,(gchar *)"con"));
    g_signal_connect(btnCon, "clicked", (GCallback)conDisplay, &ctx);

    gtk_widget_show_all(mainwin);

    gtk_main();
    return 0;
}

感谢您的帮助!

最好的问候。

1 个答案:

答案 0 :(得分:0)

来自GtkBuilder

  

GtkBuilder拥有对其构造的所有对象的引用,并在最终确定时删除这些引用。此终结可能导致销毁未包含在顶层窗口中的非窗口小部件对象或窗口小部件。对于由构建器构造的顶层窗口,用户有责任调用gtk_widget_destroy()来删除它们及其包含的所有小部件。

GtkDialog inherits from GtkWindow后我建议将mainwindlg GtkBuilders和gladefiles分开,并在GtkBuilder中使用临时conDisplay

void conDisplay(GtkWidget *g, gpointer userdata) {
    GtkWidget *dlg, *parent;
    Context *ctx=(Context *)userdata;
    GtkBuilder *builder = gtk_builder_new_from_file("dlg.glade"); //or even pass glade filename in Context
    /* rest of the code */
    gtk_widget_destroy(GTK_WIDGET(dlg));
    g_object_unref(G_OBJECT(builder));
}