这里有一个简短的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;
}


谢谢你的帮助 !

最好的祝福。

V.

最佳答案

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));
}

关于c - GTK3:gtk_widget_destroy与gtk_widget_hide,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49107222/

10-11 21:12