GTK mise en œuvre de MessageBox

voix
28

Je suis en train de mettre en œuvre Win32 en MessageBoxutilisant GTK. L'application en utilisant SDL / OpenGL, ce n'est donc pas une application GTK.

Je gère l'initialisation ( gtk_init) sorte de choses à l' intérieur de la MessageBoxfonction comme suit:

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

Maintenant, je suis pas un programmeur expérimenté GTK, et je me rends compte que je fais probablement quelque chose horriblement mal.

Cependant, mon problème est que la dernière boîte de dialogue surgit avec cette fonction reste autour jusqu'à ce que le processus se termine. Des idées?

Créé 02/08/2008 à 00:27
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
16

Hmm, ok. Je vous suggère de code comme cela, alors:

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
}

Le struct est parce que vous devez passer autour d' un couple des morceaux de données. L' gtk_idle_add()appel ajoute une méthode à exécuter lorsque la boucle principale est en cours d' exécution et de repos, et la FALSEvaleur de retour de l' display_dialog()appel signifie qu'il est exécuté qu'une seule fois. Après avoir obtenu le résultat de la boîte de dialogue, nous abandonnons la boucle principale. Cela va provoquer le gtk_main()dans votre principale MessageBox()méthode pour revenir, et vous serez en mesure d'accéder au résultat à partir de là.

J'espère que cela t'aides!

Créé 03/08/2008 à 03:30
source utilisateur

voix
6

Pour gérer une boîte de dialogue avec GTK +, utilisez un GtkDialog et gtk_dialog_run () au lieu de gérer une fenêtre et une boucle principale par vous - même.

EDIT / ADDENDA:

Ce que je veux dire est « utilise juste »: Je ne comprends pas pourquoi vous créez une fenêtre que vous utilisez jamais et une boucle principale qui semble inutile (au moins du morceau de code affiché). Vous pouvez écrire quelque chose d'aussi court que:

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;
    } 
}
Créé 02/06/2010 à 16:59
source utilisateur

voix
5

Quelques choses:

Vous créez (et ne pas utiliser) une fenêtre toplevel inutile, nommé window. Vous pouvez simplement supprimer ces lignes:

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

En outre, le flux ne semble pas tout à fait raison. gtk_main()commence la boucle principale GTK, qui bloque jusqu'à ce que quelque chose de sa sortie. gtk_dialog_run()démarre également une boucle principale, mais il sort dès que l' un des boutons est cliqué.

Je pense qu'il pourrait être suffisant pour vous de supprimer les gtk_init_add()et gtk_main()appels, et simplement faire face à la valeur de retour. Aussi l' gtk_widget_destroy()appel est inutile, car la fenêtre de dialogue est détruit automatiquement lorsque gtk_dialog_run () retourne.

Créé 02/08/2008 à 19:49
source utilisateur

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