Seitenleiste

Menüleisten

Menü- und Werkzeugleiste
Es ist zum Standard bei Anwendungen geworden, diese mit einer Menüleiste auszustatten. Dort gibt es klassischerweise die Menüs „Datei“, „Bearbeiten“ und „Ansicht“, oft auch mehr. Oft benutzte Funktionen, auf die man schnell zugreifen sollte, packt man am besten in eine Werkzeugleiste. Dort findet man oft Icons, die für die Funktionen stehen.

Menübar Das Zentrum eines GTK-Menüs 1) bildet die GtkMenuBar. In die GtkMenuBar packt man dann GtkMenuItems. Um ein aufklappendes Menü zu erzeugen benutzt man ein GtkMenu. Dieses verbindet man mit einem GtkMenuItem in der GtkMenuBar. In das GtkMenu kann man dann wieder GtkMenuItems packen.

Kommen wir zur Umsetzung: Als Basis benutzt bitte das leere Fenster aus dem Kapitel Erste Schritte mit GTK+ und erweitert es mit einer vertikalen Box.

Um eine Menüleiste mit einem Menu („Datei“) und einem Eintrag („Beenden“) zu erstellen, benötigen wir zudem 4 weitere GtkWidgets:

GtkWidget *menubar,  /*die Menüleiste an sich: wird später in die vertikale Box gepackt*/
          *filemenu, /*das "Datei"-Menü, in das wir das Beenden-Item stecken.*/
          *fileitem, /*das "Datei"-Item: kommt in die Menüleiste und wird mit "filemenu" verknüpft*/
          *quititem; /*das "Beenden"-Item*/

Als nächstes erstellen wir menubar und filemenu, mit der Gtk üblichen *_new Funktion:

menubar = gtk_menu_bar_new();
filemenu = gtk_menu_new();

Nun kommen die GtkMenuItems an die Reihe. Allerdings sollte man hier zwischen verschiedenen Typen unterscheiden:

TypBeschreibungFunktion zum Erstellen
GtkMenuItemEin einfaches Item, nur mit Text
gtk_menu_item_new_with_label(const gchar *text)
gtk_menu_item_new_with_mnemonic(const gchar *text)
GtkImageMenuItemEin Item mit einem kleinen Icon, welches über eine GTK_STOCK_ID gesetzt werden kann 2)
gtk_image_menu_item_new(void)
gtk_image_menu_item_new_from_stock(const gchar *stock, GtkAccelGroup *ag)
GtkSeparatorMenuItemEin einfacher Trennstrich, um bestimmte Bereiche zu gruppieren.
gtk_separator_menu_item_new()
GtkCheckMenuItemEin Item mit einem abhakbaren Kästchen (Check Box)
gtk_check_menu_item_new_with_label(const gchar *text)
gtk_check_menu_item_new_with_mnemonic(const gchar *text)
GtkTearoffMenuItemEin Item zum Ablösen des GtkMenus von der Menüleiste, dargestellt als durchzogene, gepunktete Linie.
gtk_tearoff_menu_item_new()

Mnemonics

Bei mehreren oben aufgelisteten MenuItems tauchen Mnemonics auf. Als Mnemonic bezeichnet man in GTK die Hervorhebung eines Buchstaben durch einen Unterstrich. Ist das Menü offen, so kann der Benutzer durch Drücken der Taste des unterstrichenen Buchstabens das jeweilige Menü-Item aktivieren, also die Aktion ausführen. Folgende Funktion erstellt ein Menü-Item mit dem Label (=Text) „Datei“:

fileitem = gtk_menu_item_new_with_mnemonic("_Datei");

Wie ihr seht, geht dem jeweiligen Buchstaben, der mit einem Mnemonic3) verziert werden soll, ein Unterstrich vor. Bemüht euch bei der Vergabe von Mnemonics darum, dass sie auch dem Benutzer einleuchtend sind und er nicht erst auf den unterstrichenen Buchstaben achten muss.

Gtk Stocks

Auch müssten euch bei der obigen Tabelle Funktionen aufgefallen sein, die auf *_from_stock enden. Diese erwarten dann die Angabe einer „STOCK_ID“. Zunächst einmal: Was sind Gtk Stocks?

Oft sieht man in GTK und GNOME-Anwendungen (Image-)Menü-Items mit Icons, die immer gleich sind. Oft werden diese über GTK-STOCKS 4) realisiert. Praktisch sind die GtkStocks eine ganze Reihe von Defines, die immer mit GTK_STOCK_* beginnen.

Bei Menü-Items benutzt für die Verwendung von Stocks das GtkImageMenuItem. Um dann ein Beenden-Item, wie ganz oben auf dem Bild zu sehen zu erzeugen, genügt folgender Aufruf:

quititem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);

Eine vollständige Liste von Gtk Stocks (auch mit schönen Bildchen =)) findet ihr in der GTK-Referenz.

Zusammenpacken...

Nun haben wir grundlegendsten Bestandteile einer Menüleiste erstellt, doch haben wir noch lange nicht eine fertige Menüleiste!

Zunächst sei noch einmal ein Blick auf das oben gezeigte Diagramm empfohlen, um zu verstehen, was wir in was packen müssen.

Als erstes Setzen wir unser Beenden-Item (das mit dem Gtk Stock) in unser GtkMenu, welches später über „Datei“ erreichbar sein soll. Folgende Zeile reicht da vollkommen aus:

gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quititem); 

Als nächstes Packen wir unser „Datei“ Item (fileitem) in unsere GtkMenuBar:

gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileitem); 

Zum Schluss müssen wir nur noch festlegen, dass beim Klicken des Datei Items auf das Datei-Menü (mit unserem Beenden-Item) erscheint:

gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu); 

Um das alles auch im Fenster sehen zu können, müsst ihr natürlich noch die GtkMenuBar menubar in die vertikale Box packen.

Signale

Noch ein kurzer Blick auf die Verwendung von Signalen bei Menü-Items. Um unser kleines Programm bei Klick auf das Beenden Symbol wirklich zu beenden, müssen wir es natürlich verknüpfen, und zwar mit gtk_main_quit5):

g_signal_connect(quititem, "activate", G_CALLBACK(gtk_main_quit), NULL);

Wie unschwer zu erkennen ist, benutzt jedes GtkMenuItem das „activate“ Signal.

Last but not least...

Für die Faulen unter euch, hier noch einmal der vollständige Code (bis jetzt, wir wollen diesen noch um eine Werkzeugleiste erweitern):

#include <gtk/gtk.h>
 
int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *menubar,  /* die Menüleiste an sich: wird später in die vertikale Box gepackt */
	      *filemenu, /* das "Datei"-Menü, in das wir das Beenden-Item stecken. */
    	      *fileitem, /* das "Datei"-Item: kommt in die Menüleiste und wird mit "filemenu" verknüpft */
    	      *quititem; /* das "Beenden"-Item */
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);
 
    /* Erstellen der Menüleiste und der anderen Menü Bestandteile */
    menubar = gtk_menu_bar_new();
    filemenu = gtk_menu_new();
    fileitem = gtk_menu_item_new_with_mnemonic("_Datei");
    quititem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
 
    /* Packen */
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quititem); 
    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileitem); 
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu); 
 
    gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
 
    /* Ein neues Signal */
    g_signal_connect(quititem, "activate", G_CALLBACK(gtk_main_quit), NULL);
 
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
 
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

In der nächsten Lektion werdet ihr dann die Werkzeugleisten kennen lernen. Dafür werden wir den obenstehenden Quelltext erweitern.

zurück || hoch zur Startseite || weiter


Diskussion

1)
besser: „Menüleiste“
2)
es kann auch über ein externes Bild gesetzt werden
3)
englisch etwa: Abkürzung, Eselsbrücke, Gedänchtnisstütze
4)
stock: englisch: Vorrat, Lager
5)
Dieses beendet den GtkMainLoop, der Programmablauf geht dann nach dem Aufruf von gtk_main() weiter.