c -消息框的GTK实现

Translate

我一直在尝试实现Win32MessageBox使用GTK。该应用程序使用SDL / OpenGL,因此它不是GTK应用程序。

我处理初始化(gtk_init)里面的东西MessageBox功能如下:

int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *window = NULL;
    GtkWidget *dialog = NULL;

    gtk_init(&gtkArgc, &gtkArgv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
    // gcallback calls gtk_main_quit()
    gtk_init_add((GtkFunction)gcallback, NULL);

    if (type & MB_YESNO) {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
    } else {
        dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
    }

    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));

    gtk_main();

    gtk_widget_destroy(dialog);

    if (type & MB_YESNO) {
        switch (result) {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
            break;
        case GTK_RESPONSE_YES:
            return IDYES;
            break;
        }
    }

    return IDOK;
} 

现在,我绝不是一位经验丰富的GTK程序员,而且我意识到自己可能在做一些可怕的错误。

但是,我的问题是,使用该功能弹出的最后一个对话框会一直存在,直到进程退出。有任何想法吗?

This question and all comments follow the "Attribution Required."

所有的回答

Translate

嗯。。好。我建议这样的代码,然后:

typedef struct {
    int type;
    int result;
} DialogData;

static gboolean
display_dialog(gpointer user_data)
{
    DialogData *dialog_data = user_data;
    GtkWidget *dialog;

    if (dialog_data->type & MB_YESNO)
        dialog = gtk_message_dialog_new(...);
    else
        dialog = gtk_message_dialog_new(...);

    // Set title, etc.

    dialog_data->result = gtk_dialog_run(...);

    gtk_main_quit();  // Quits the main loop run in MessageBox()

    return FALSE;
}

int MessageBox(...)
{
    DialogData dialog_data;

    dialog_data.type = type;

    gtk_idle_add(display_dialog, &dialog_data);

    gtk_main();

    // Do stuff based on dialog_data.result
}

该结构是因为您需要传递一些数据。的gtk_idle_add()调用添加了一个在主循环正在运行和空闲时运行的方法,并且FALSE从返回值display_dialog()调用意味着它只能运行一次。从对话框中获得结果后,我们退出主循环。那会导致gtk_main()在你的主要MessageBox()方法返回,您将可以从那里访问结果。

希望这可以帮助!

来源
Translate

要使用GTK +管理对话框,请使用GtkDialog和gtk_dialog_run()而不是自己管理窗口和主循环。

编辑/附录:

我的意思是“正当使用”:我不明白为什么您创建了一个从未使用过的窗口以及一个似乎无用的主循环(至少从您发布的代码中)。您可以编写简短的内容:

int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
    GtkWidget *dialog ;

    /* Instead of 0, use GTK_DIALOG_MODAL to get a modal dialog box */

    if (type & MB_YESNO)
        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text );
    else
        dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text );


    gtk_window_set_title(GTK_WINDOW(dialog), caption);
    gint result = gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy( GTK_WIDGET(dialog) );

    if (type & MB_YESNO)
    {
        switch (result)
        {
        default:
        case GTK_RESPONSE_DELETE_EVENT:
        case GTK_RESPONSE_NO:
            return IDNO;
        case GTK_RESPONSE_YES:
            return IDYES;
        }
        return IDOK;
    } 
}
来源
Translate

一些东西:

您正在创建(而不使用)不必要的顶层窗口,名为window。您可以删除以下几行:

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

另外,流程似乎不太正确。gtk_main()启动GTK主循环,该循环将阻塞直到有东西退出。gtk_dialog_run()也会启动一个主循环,但是一旦单击其中一个按钮,它就会退出。

我认为您只需删除gtk_init_add()gtk_main()调用,并简单地处理返回值。还有gtk_widget_destroy()调用是不必要的,因为gtk_dialog_run()返回时,对话框窗口会自动销毁。

来源
下一个问题:
c++ -BerkeleyDB并发