Seitenleiste

Werkzeugleisten

WerkzeugleisteNeben den in der letzten Lektion behandelten Menüleisten werdet ihr mit Sicherheit in vielen Anwendungen auch eine weitere Leiste finden, die Werkzeugleiste. Sie gibt dem Benutzer die Möglichkeit, schnell und einfach auf oft benutzte Funktionen zuzugreifen.

Daher werden oft nur Icons benutzt, da sie deutlich intuitiver zu verstehen sind.

Der Einsatz

Eine Werkzeugleiste in GTK (GtkToolbar) ist deutlich einfacher zu handhaben als eine Menüleiste, solange man die Buttons in der Werkzeugleiste nicht verschachteln will.

GtkWidget *toolbar; /*die Werkzeugleiste persönlich*/
GtkToolItem *toolquit; /*der Button zum Beenden, der in die Werkzeugleiste soll*/

Das Erstellen der Elemente gestaltet sich auch nicht viel schwieriger, rufen wir wieder die „GTK *_new“ Funktion auf:

toolbar = gtk_toolbar_new();
toolquit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT);

Wie zu sehen, verwenden wir wieder ein GTK_STOCK, und zwar wieder mit dem „Beenden“ Symbol.

Als nächstes muss toolquit in toolbar:

gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolquit, -1);

Dazu benutzen wir gtk_toolbar_insert. Die ersten beiden Argumente dürften soweit klar sein, einmal die Werkzeugleiste, dann das GtkToolItem. Doch was macht diese -1 da am Ende?

Laut GTK-Referenz legen wir hiermit die Position des Buttons fest. Das erste Item hat Position 0, das zweite 1 und so weiter…

Dabei muss, um ein Item auf 1 zu setzen, ein Item auf 0 sein. Setzen wir dann ein Item auf 0, wird es eingefügt, also alle anderen danach werden um eine Stelle nach hinten verschoben. Bleibt nur die Frage: was bewirkt -1?

Antwort: Mit -11) wird das Item an die letzte Position in der Leiste gestellt.

Am besten erweitert ihr den Code aus der letzten Lektion (Menüleisten): Dann könnt ihr nämlich folgende Zeile per Copy&Paste übernehmen, die Funktion sollte klar sein:

gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);

Von GLib, GObject und OOP

An dieser Stelle sei ein kleiner Blick auf die grundlegenden Funktionen von GTK und die Geschichte dieser Bibliothek gestattet. Das Gimp-Toolkit wurde ursprünglich für das freie Grafikprogramm GIMP geschrieben. Damals hatte man oft benutzte, aber für den Programmierer sehr aufwendige Funktionen in eine Bibliothek ausgelagert, in GTK.

So entwickelte sich eine Technik, um objektorientiert in C zu programmieren. Da C über keine Unterstützung für objektorientierte Programmierung verfügt, musste man die erforderlichen Strukturen erst schaffen.

Daraus entstand eine Grundstruktur, das GObject. Alle Datenstrukturen (Objekte) in GTK besitzen als erste Datenwerte die von GObject, in der objektorientierten Programmierung (OOP) spricht man von Vererbung.

Zurück zur Geschichte. Mit der Zeit suchte man nach einem Ersatz für die GUI-Bibliothek Motif, die damals auf unixartigen Betriebssystemen am meisten genutzt wurde. So erweiterte man GTK um eine GUI-Bibliothek und lagerte praktisch alle anderen Funktionen in die GLib aus, die GTK heute noch nutzt. Als Zeichensystem wird GDK verwendet, das Gimp Drawing Kit, welches allerdings immer mehr als „veraltet“ angesehen wird, da es sehr langsam ist. Seit GTK3 ist GDK veraltet (deprecated). Stattdessen wird Cairo verwendet.

Nun hat die GLib ihr Basisobjekt in GObject, GTK in GtkObject 2). GtkObject ist aber auch von GObject abgeleitet, d.h. es enthält Merkmale von GObject. Ebenso verhält es sich mit GtkWidget und GtkObject. Man sagt auch: Ein GtkWidget ist ein GtkObject und ein GtkObject ist ein GObject. Aber: Ein GObject ist kein GtkWidget.

An dieser Stelle ergab sich jedoch für die GLib-Entwickler ein Problem: Definiert man in C ein Struct, so lassen sich zwar Membervariablen definieren, aber weder Methoden noch Vererbung kann man sinnvoll in C implementieren. Die Lösung lässt sich am Beispiel von GTK am besten erklären: Wir haben eine Variable vom Typ GtkWidget, dem Basisobjekt von GTK:

GtkWidget *our_widget;

Nun füllen wir our_widget mit Inhalt, und zwar einem GtkWindow.

our_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);

Allerdings gibt es für das Fenster in GTK eine eigene Struktur: GtkWindow. our_widget enthält deshalb einen Verweis auf die Struktur. Nun wollen wir die Größe unseres Fensters ändern. Dafür nutzen wir gtk_window_set_default_size(). Diese Funktion erwartet aber ein GtkWindow als erstes Argument:

gtk_window_set_default_size(our_widget, 200, 200);

führt zu einer Kompilerwarnung, da es sich um inkompatible Zeigertypen handelt. Diesen Fehler sollte jeder C-Compiler erkennen.

gtk_window_set_default_size(GTK_WINDOW(our_widget), 200, 200); 

keine Warnungen, alles funktioniert. Dies ist der beste Weg. GTK_WINDOW() ist ein GLib-Cast, der GtkWidget in GtkWindow „umwandelt“. Dies funktioniert, weil our_widget schon mit dem Inhalt eines GtkWindows „gefüllt“ wurde. Sehen wir uns nun folgendes Beispiel an:

gtk_box_pack_start(GTK_BOX(our_widget), other_widget, FALSE, FALSE, 0);
 

Nun benutzen wir den GLib-Cast zu GtkBox. Der Kompiler spuckt keine Warnung aus, aber beim Ausführen meldet sich die GLib:

(test1:4538): GLib-GObject-WARNING **: invalid cast from `GtkWindow' to `GtkBox'

Denn our_widget ist keine GtkBox. Es ist ein GtkWidget und ein GtkWindow.

An dieser Stelle sei der (nicht so kleine) Exkurs zur GLib in die Geschichte von GTK beendet. Was ihr aber unbedingt nun wissen solltet:

Mit der GLib ist es möglich, in C auf eine gewisse Art und Weise objektorientiert zu programmieren. Im Gegensatz zu „echten“ objektorientierten Sprachen wie C++ oder Java, entfällt die Typüberprüfung während der Kompilierzeit auf die Laufzeit. Das heißt: Einen ungültigen (invaliden) Cast schluckt jeder C-Compiler anstandslos, erst beim Starten des Programms meldet sich die GLib und beklagt sich.
Manche Leute behaupten, durch die GLib gehe die eigentliche Typsicherheit von C verloren.

Aus diesem Grunde: achtet auf eure Casts, bei der Entwicklung mit GTK werdet ihr sie immer wieder gebrauchen (müssen).

Falls ihr mehr über GObject wissen wollt, oder sogar eigene Objekte erstellen wollt, schaut euch das GObject Tutorial hier auf proggen.org an. Ihr findet eine Übersicht auf der GTK-Startseite.

Zurück zur GtkToolbar

Weiter geht es mit dem eigentlichen Thema dieser Lektion: GtkToolbar. Diese besitzt nämlich noch ein interessantes Feature, auf das ich gerne noch einmal eingehen möchte: dem GtkToolbarStyle. Mit dieser Eigenschaft lässt sich die Darstellung einer Toolbar in GTK anpassen. Die Benutzung ist recht simpel:

gtk_toolbar_set_style(GtkToolbar* toolbar, GtkToolbarStyle style);

Das erste Funktionsargument dürfte jedem klar sein, hinter dem zweiten verbirgt sich ein enum:

Style Beschreibung
GTK_TOOLBAR_ICONSDie GtkToolItems werden nur mit den Icons dargestellt, der Text fällt weg.
GTK_TOOLBAR_TEXTHier fallen die Icons weg, nur der entsprechende Text wird dargestellt.
GTK_TOOLBAR_BOTHSowohl Text als auch Icon werden angezeigt, und zwar untereinander.
GTK_TOOLBAR_BOTH_HORIZWie GTK_TOOLBAR_BOTH, nur nebeneinander.

Ausblick...

…und schon wieder ist eine Lektion vorüber, doch dies war eine Besondere: Mit ihr endet das erste Kapitel. Toll, werdet ihr jetzt denken, aber die wichtigsten Elemente einer GUI dürftet ihr nun mit GTK+ darstellen können. Natürlich reicht das noch nicht für eine vollständige, benutzbare Anwendung, aber das kann ja noch werden. Im zweiten Kapitel werden wir einen Texteditor in GTK schreiben. Dabei wird zwar auch viel aus den bisherigen Lektionen benutzt, aber der Großteil wird neu sein, schaut einfach mal rein!

zurück || hoch zur Startseite

1)
oder jeder anderen negativen (Ganz-)Zahl
2)
Ab GTK3 sind alle GTK Klassen direkt von GObject abgeleitet