ein Kapitel zurück                                           ein Kapitel weiter

Damit man auch Anwenderfreundliche Programme schreiben kann, benötigen wir natürlich dazu Menüs. GTK kennt mehrere Möglichkeiten Menüs zu erstellen. Vorerst wollen wir uns die einfachste Möglichkeit dazu ansehen.

GtkItemFactory

Logischerweise ist auch hier wieder der 1.Schritt, das Menü-Widget zu erzeugen:

GtkItemFactory * gtk_item_factory_new(GtkType *Container_type,
                                      const gchar *path,
                                      GtkAccelGroup *accl_group);  

Für den Containertyp können sie folgende Arten von Menüs erzeugen:

GTK_TYPE_MENU_BAR
GTK_TYPE_MENU
GTK_TYPE_OPTION_MENU  

Der path ist ein eindeutiger Name in spitzen Klammern für die Menüleiste. Mit accl_group können sie einen Zeiger auf Tastatur-Kürzel definieren.

Mit dem nächsten Schritt wird anschließend die Menüleiste erstellt. Die mit der Funktion:

void gtk_item_factory_create_items(GtkItemFactory *ifacrory,
                                   quint n_entries,
                                   GtkItemFactoryEntry *entries,
                                   gpointer callback_data);  

ifactory ist ein Zeiger auf das kurz zuvor erzeugte GtkItemFactory. n_entries erhält die Anzahl der Menüeintrage. entries ist ein Zeiger auf die Struktur GtkItemFactoryEntry welche die Einträge in der Menüleiste beinhaltet. Folgende 5 Eintrage werden dabei für die Menüleiste gemacht. Der Reihe nach:

  • Menüpfad - wird genauso verwendet wie bei einer Verzeichnis-Struktur.
  • Tastaturkürzel - Damit lassen sich die Menüeinträge von Tastatur steuern. Beispielsweise <shift>X oder <control>B, <alt>V.......
  • Callbackfunktion - Wie gehabt, ein Callbackfunktion die Aufgerufen werden soll bei betätigen des Menüeintrags.
  • Parameter für die Callbackfunktion - spricht für sich
  • Itemtyp - Art des zu erstellenden Menüeintrags. Folgende Möglichkeiten haben sie dafür zur Verfügung:

    • "<Title>" Titeleintrag
    • "<Item>" Normaler Menüeintrag
    • "<CheckItem>" Checkmenüeintrag
    • "<RadioItem>" Radiomenüeintrag
    • "<ToggleItem>" Toogleeintrag
    • <path> Pfad zu restlichen Radiomenüeinträgen
    • "<Seperator>" Trennlinie
    • "<Tearoff>" Abreißkante
    • "<Branch>" Eintrag der Untereinträge aufnehmen kann
    • "<LastBranch>" Rechtsausgerichteter Menüeintrag
    • NULL "" Normaler Menüeintrag

Und so hat man sich einen solchen Eintrag vorzustellen:

static GtkItemFactoryEntry menue[] =
       {
         { "/_File", NULL, NULL, 0, "<Branch>" },
         { "/File/_Neu", "<control>N", new_file, 0, NULL}
       };  

Kein Sorge, wir sehen uns das anschließen in einem Programmbeispiel an.

Nun noch zu GtkAccelGroup womit wir einen Zeiger auf die eben genannte Struktur für Tasten-Kürzel erstellen. Erzeugen können wir dies mit:

GtkAccelGroup *gtk_accel_group_new(void);  

Dies Struktur müssen wir natürlich auch einem Widget (meist dem Fenster) zuordnen. Dies machen wir mit der Funktion:

void gtk_accl_group_attach(GtkAcclGroup *accl_group,
                           GtkObjekt    *object);  

Nun wird es Zeit für ein Programmbeispiel:

/*Download:gtk_men.c*/

#include <gtk/gtk.h>
#include <stdio.h>

GtkItemFactory *items;
GtkAccelGroup *accl;

/*Programmende*/
void ende_cb(GtkObject *object)
{
 gtk_main_quit();
}

void file_open(GtkWidget *widget, gpointer data)
{
 g_print("Datei öffnen\n");
}

void file_save(GtkWidget *widget, gpointer data)
{
 g_print("Datei speichern\n");
}

void file_close(GtkWidget *widget, gpointer data)
{
 g_print("Datei schließen\n");
}

void cut(GtkWidget *widget, gpointer data)
{
 g_print("Ausschneiden\n");
}

void copy(GtkWidget *widget, gpointer data)
{
 g_print("Kopieren\n");
}

void help(GtkWidget *widget, gpointer data)
{
 g_print("Hier gibt es keine Hilfe!\n");
}

/*Die Menüeintrage*/
static GtkItemFactoryEntry menue[]={
  { "/_Datei", NULL, NULL, 0, "<Branch>" },
  { "/Datei/Öffnen", "<control>O", file_open, 0, NULL},
  { "/Datei/Speichern", "<control>S", file_save, 0, NULL},
  { "/Datei/Schließen", "<control>C", file_close, 0, NULL},
  { "/Datei/Ende", "<control>Q", gtk_main_quit, 0, NULL},

  { "/Bearbeiten", NULL, NULL, 0, "<Branch>" },
  { "/Bearbeiten/Ausschneiden", "<control>X", cut, 0, NULL},
  { "/Bearbeiten/Kopieren", "<control>P", copy, 0, NULL},
  { "/?", NULL, NULL, 0, "<LastBranch>"},
  { "/?/Hilfe", NULL, help, 0, NULL},
  };





int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkItemFactory *items;
 GtkAccelGroup *accl;
 GtkWidget *box;
 GtkWidget *menu_bar;
 gint n_menue = sizeof(menue) /sizeof(menue[0]);

 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 accl=gtk_accel_group_new();
 items=gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accl);
 gtk_item_factory_create_items(items, n_menue, menue, NULL);
 gtk_accel_group_attach(accl, GTK_OBJECT(fenster));
 menu_bar=gtk_item_factory_get_widget(items, "<main>");
 /*Buttons erstellen*/
 gtk_window_set_default_size(GTK_WINDOW(fenster), 320, 300);


 /*Neue Box erstellen*/
 box = gtk_vbox_new(FALSE,0);


 /*Signale registrieren*/
 gtk_signal_connect(GTK_OBJECT(fenster), "destroy",
                    GTK_SIGNAL_FUNC(ende_cb), NULL);

 /*Fensterposition*/
 gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER);



// gtk_container_set_border_width(GTK_CONTAINER(fenster),15);

 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, TRUE, 0);


 gtk_container_add(GTK_CONTAINER(fenster),box);

 /*Zeigs uns.....*/
 gtk_widget_show_all(fenster);

 gtk_main();

 return 0;
}

Und so könnte es aussehen:




Es gibt noch ein Unmengen von Funktionen, welche ich von Zeit zu Zeit hier ergänzen werde.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf