Implementace GTK z MessageBox

hlasů
28

Byl jsem se snaží realizovat své Win32 MessageBoxpomocí GTK. Aplikace pomocí SDL / OpenGL, takže to není GTK aplikace.

Starám se o inicializaci ( gtk_init) druh věcí uvnitř MessageBoxfunkce takto:

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

Teď jsem v žádném případě zkušeného GTK programátor, a uvědomuji si, že jsem asi něco strašně špatně.

Nicméně, můj problém je, že poslední dialog vyskočila se tato funkce zůstane kolem, dokud proces skončí. Nějaké nápady?

Položena 02/08/2008 v 00:27
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
16

Hmm, ok. Já bych navrhnout kód, jako je toto, pak:

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
}

Struct je proto, že je třeba projít kolem pár kousků dat. gtk_idle_add()Volání přidává metodu ke spuštění při spuštění hlavní smyčku a nečinný, a FALSEnávratová hodnota z display_dialog()volání znamená, že je to běh pouze jednou. Poté, co jsme ten výsledek z dialogu, jsme opustit hlavní smyčku. To bude způsobit, že gtk_main()v hlavním MessageBox()způsobem vrátit, a budete mít možnost získat přístup k výsledku odtamtud.

Snad to pomůže!

Odpovězeno 03/08/2008 v 03:30
zdroj uživatelem

hlasů
6

Chcete-li spravovat dialogové okno s GTK +, použijte GtkDialog a gtk_dialog_run () namísto řídit okna a hlavní smyčku sami.

EDIT / DODATEK:

Co mám na mysli, je „prostě použít“: Nechápu, proč si vytvořit okna nikdy použít a hlavní smyčku, která se zdá být zbytečné (alespoň z kus kódu, který vyslán). Můžete napsat něco tak krátkou, jako jsou:

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;
    } 
}
Odpovězeno 02/06/2010 v 16:59
zdroj uživatelem

hlasů
5

Pár věcí:

Vytváříte (nepoužívají) zbytečně toplevel okno, pojmenované window. Stačí odstranit tyto řádky:

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

Také proud nezdá úplně v pořádku. gtk_main()spustí hlavní smyčku GTK, která blokuje, dokud něco ho ukončí. gtk_dialog_run()Také spustí hlavní smyčku, ale ukončí, jakmile je jedno z tlačítek klepnutí.

Myslím, že by to mohlo být dost pro vás, aby se odstranily gtk_init_add()i gtk_main()hovory, a jednoduše jednat s návratovou hodnotou. Také gtk_widget_destroy()volání je zbytečné, protože dialogové okno automaticky zničena, když gtk_dialog_run přiznání ().

Odpovězeno 02/08/2008 v 19:49
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more