GTK uitvoering van MessageBox

stemmen
28

Ik heb geprobeerd uit te voeren Win32's MessageBoxmet behulp van GTK. De app gebruik van SDL / OpenGL, dus dit is niet een GTK app.

Ik omgaan met de initialisatie ( gtk_init) soort dingen in de MessageBoxfunctie als volgt:

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

Nu, ik ben geenszins een ervaren GTK programmeur, en ik realiseer me dat ik waarschijnlijk iets vreselijk verkeerd doe.

Maar mijn probleem is dat de laatste dialoog dook met deze functie mag rond totdat het proces wordt afgesloten. Iemand een idee?

De vraag is gesteld op 02/08/2008 om 00:27
bron van user
In andere talen...                            


3 antwoorden

stemmen
5

Een paar dingen:

Jullie creëren (en niet met behulp van) een onnodige toplevel venster, namelijk window. Je kunt gewoon deze lijnen te verwijderen:

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

Ook heeft de stroom lijkt niet helemaal goed. gtk_main()start de GTK hoofdlus, welke blokken tot er iets verlaat het. gtk_dialog_run()Ook begint een van de belangrijkste loop, maar het wordt uitgevoerd zodra een van de knoppen wordt geklikt.

Ik denk dat het misschien genoeg zijn voor u om het te verwijderen gtk_init_add()en de gtk_main()gesprekken en gewoon te gaan met de return waarde. Ook de gtk_widget_destroy()oproep is niet nodig, als het dialoogvenster automatisch wordt vernietigd wanneer gtk_dialog_run () rendementen.

antwoordde op 02/08/2008 om 19:49
bron van user

stemmen
16

Hmm oke. Ik zou code voorstellen als dit, dan:

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
}

De structuur is, want je moet een paar stukken van de gegevens rond te passen. De gtk_idle_add()oproep voegt een methode die moet worden uitgevoerd wanneer de belangrijkste lus loopt en niet actief is en de FALSEreturn waarde van de display_dialog()call betekent dat het slechts één keer wordt gerund. Nadat we de resultaten van de dialoog, we stoppen met de hoofdlus. Dat zal ertoe leiden dat de gtk_main()in uw belangrijkste MessageBox()methode om terug te keren, en u zult in staat zijn om toegang te krijgen tot het resultaat vanaf daar.

Ik hoop dat dit helpt!

antwoordde op 03/08/2008 om 03:30
bron van user

stemmen
6

Om een dialoogvenster met GTK + beheren, gebruik dan een GtkDialog en gtk_dialog_run () in plaats van het beheer van een raam en een hoofdlus door uzelf.

EDIT / ADDENDUM:

Wat ik bedoel is "gewoon gebruik": Ik begrijp niet waarom je een windows u nooit gebruikt en een van de belangrijkste lus die nutteloos lijkt (althans van het stukje code u op de hoogte) te creëren. U kunt iets zo kort schrijven:

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;
    } 
}
antwoordde op 02/06/2010 om 16:59
bron van user

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