Seitenleiste

Dialoge

Eine gute Benutzeroberfläche besteht nicht nur aus einem großen Fenster, in dem alle Widgets untergebracht sind. Bei Meldungen, wie zum Beispiel einer Fehlermeldung oder einer Information, kommen oft kleine Fenster ins Spiel, welche nur aus einer kleinen Meldung, einem Icon und einem (oder auch mehreren) Buttons bestehen.

GTK bietet hierfür ein eigenes Widget an, den GtkMessageDialog. Der GtkMessageDialog ist nur einer von vielen GtkDialogs, zu denen auch Datei-Auswahl-Dialoge und Dialoge zur Auswahl einer Farbe oder einer Schriftart gehören.

Dialog erstellen und starten

In das Grundgerüst einer GTK-Anwendung (siehe Kapitel 1 - Ein ganz einfaches GTK-Programm) schreiben wir nun folgende Zeilen, um eine Fehlermeldung zu erstellen:

GtkWidget *error_msg;
error_msg = gtk_message_dialog_new(NULL,
                                   GTK_DIALOG_MODAL,
                                   GTK_MESSAGE_ERROR,
                                   GTK_BUTTONS_OK,
                                   "Ein Fehler ist aufgetreten.");
gtk_dialog_run(GTK_DIALOG(error_msg));
gtk_widget_destroy(error_msg);

Befassen wir uns mit der Erstellung eines neuen MessageDialogs. gtk_message_dialog_new verlangt 5 Argumente:

  • das Eltern-Fenster, ein GtkWindow: bei uns NULL, da wir keines haben.
  • zusätzliche Eigenschaften, die der Dialog haben soll: mit GTK_DIALOG_MODAL wird die Interaktion mit allen anderen Fenstern der Anwendung verhindert, mit GTK_DIALOG_DESTROY_WITH_PARENT wird der Dialog mit dem Eltern-Fenster geschlossen
  • den Typ der Meldung: GTK_MESSAGE_ERROR für Fehler, weitere Typen werden weiter unten behandelt
  • die gezeigten Buttons: GTK_BUTTONS_OK für einen „OK“ Button, GTK_BUTTONS_CANCEL für einen „Abbrechen“ Button
  • die eigentlich Meldung als const gchar *

Mit gtk_dialog_run wird der neue MessageDialog gestartet. gtk_dialog_run erwartet ein GtkDialog, weshalb unser GtkMessageDialog erst mit GTK_DIALOG gecastet werden muss.

gtk_widget_destroy „zerstört“ das Widget.

Fehler, Warnung, Information

Um auch andere Typen von MessageDialogs zu erstellen, kann man statt GTK_MESSAGE_ERROR auch noch folgende Typen setzen:

Typ Wirkung
GTK_MESSAGE_ERROReine Fehlermeldung
GTK_MESSAGE_INFOeine Information
GTK_MESSAGE_WARNINGeine Warnung
GTK_MESSAGE_QUESTIONeine Frage, bei der der Benutzer eine einfache Auswahlmöglichkeit hat
GTK_MESSAGE_OTHERfür sonstige Zwecke, es wird kein Icon gezeigt

Kleines Beispiel für drei aufeinanderfolgende Dialoge:

#include <gtk/gtk.h>
 
int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
 
    GtkWidget *error_msg; 
    GtkWidget *warning_msg;
    GtkWidget *info_msg;
 
    error_msg = gtk_message_dialog_new(NULL,
				       GTK_DIALOG_MODAL,
				       GTK_MESSAGE_ERROR,
				       GTK_BUTTONS_OK,
				       "Ein Fehler ist aufgetreten.");				       
    gtk_dialog_run(GTK_DIALOG(error_msg));
    gtk_widget_destroy(error_msg);
 
    warning_msg = gtk_message_dialog_new(NULL,
				         GTK_DIALOG_MODAL,
				         GTK_MESSAGE_WARNING,
				         GTK_BUTTONS_OK,
				         "Passen sie besser auf!");
    gtk_dialog_run(GTK_DIALOG(warning_msg));
    gtk_widget_destroy(warning_msg);
 
    info_msg = gtk_message_dialog_new(NULL,
				      GTK_DIALOG_MODAL,
				      GTK_MESSAGE_INFO,
				      GTK_BUTTONS_OK,
				      "Dieses Programm endet nun.");
    gtk_dialog_run(GTK_DIALOG(info_msg));
    gtk_widget_destroy(info_msg);
 
    return 0;
}

Sollte zur Ausgabe drei verschiedener Dialoge führen.

Fragen: ja oder nein?

 Nun gibt es allerdings auch Dialoge, bei denen nicht nur ein Button zu sehen ist. Oft hat der Benutzer die Wahl, zum Beispiel beim Schließen des Fensters eines Texteditors, obwohl noch ungespeicherte Änderungen im Text vorhanden sind.

Die Umsetzung in GTK ist relativ simpel: Zuerst müssen die Buttons dem Dialog hinzugefügt werden, und zwar nicht in gtk_message_dialog_new. Dort geben wir für die Buttons GTK_BUTTONS_NONE an, also keine Buttons. Ran an den Code:

dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
                                GTK_MESSAGE_WARNING,
                                GTK_BUTTONS_NONE,
                                "Im Text befinden sich noch ungespeicherte Änderungen.");
 
gtk_dialog_add_buttons(GTK_DIALOG(dialog),
                      "Beenden", 100,
                      "Abbrechen", 101,
                      "Speichern", 102, NULL);

Uns interessiert nun die zweite Methode: Das erste Argument ist der Dialog, danach folgt eine variable Anzahl an Argumenten für die Buttons. Diese besteht aus:

  • dem Namen des Buttons (oder einer GTK_STOCK_ID)
  • der Response ID zum zuvor aufgeführten Button

Abgeschlossen werden muss die Liste mit NULL.

Doch was ist diese Response ID? Eine Response ID (deutsch etwa: „Rückmeldungs Identifikationsnummer“) wird je einem Button zugeordnet und ist eine Ganzzahl vom Typ gint. Um diese ID zu nutzen, müssen wir den Aufruf für gtk_dialog_run leicht verändern:

gint result = gtk_dialog_run(GTK_DIALOG(dialog));

Wir tun hierbei nichts anderes, als die Response ID des aktivierten Buttons abzufragen. Diese können wir dann auswerten, zum Beispiel mit einer Switch-Anweisung. Ein Beispiel1)

switch (result)
{
    case 100:
        beenden_funktion();
        break;
    case 101:
        abbruch_funktion();
        break;
    case 102:
        speicher_funktion();
        break;
}

Ausblick

Nach dieser, doch ziemlich umfangreichen Lektion solltest du nun in der Lage sein, einfache Dialoge zu erstellen und auszuführen. Als kleine Übung könnt ihr das angegebene Beispiel für den Frage-Dialog erweitern, eine Idee wäre, die Funktionen in der switch-Anweisung zu schreiben. Übung macht den Meister ;-)

zurück || hoch zur Startseite || weiter

1)
natürlich müssen die Funktionen existieren, die hier aufgerufen werden…