Die Übersichtlichkeit der Seite wird durch Javascript erhöht. Ist dies aktiviert, werden die Texte unter den Überschriften durch Anklicken der Überschriften ein- und ausgeblendet.
Unter Gnome oder XFCE sind die gtk-libs automatisch installiert. Dennoch wird der Versuch, ein Programm, wie ich es in diesem Tutorial schreibe zu kompilieren scheitern, wenn die Libs und Flags dem Compiler nicht mit übergeben werden.
Die nötigen Übergabe-Parter können wie folgt ermittelt werden:
Dies ergibt jeweils eine recht lange Ausgabe an zu übergebenden Parametern. Um nicht die kompletten Listen in den jeweiligen Befehl hineinkopieren zu müssen, kann man die genannten Befehle in Backticks (`) eingeschlossen direkt als Parameter übergeben.
g++ -Wall cpp-Dateiname `pkg-config --libs gtk+-3.0 --cflags gtk+-3.0` Programmname
Um diesen immer noch recht langen Befehl nicht immer wieder eingeben zu müssen, habe ich einen Alias vergeben:
alias cgtk='g++ -Wall `pkg-config gtk+-3.0 --libs --cflags`' alias cpgtk='g++ -Wall `pkg-config gtkmm-3.0 --libs --cflags`'
Ab sofort diese GTK-Programme auf einfache Weise wie folgt compilieren:
cgtk CPP-Dateiname [-o Programmname]
oder für Programme, die gtkmm benutzen:
cpgtk CPP-Dateiname [-o Programmname]
Wird der Programmname weg gelassen, ist der Name des Compilats a.out.
Libs: pkg-config --libs gtk+-3.0
Der Befehl:
pkg-config --libs gtk+-3.0
erzeugt bei mir folgende Ausgabe:
-lgtkmm-3.0 -latkmm-1.6 -lgdkmm-3.0 -lgiomm-2.4 -lpangomm-1.4 -lglibmm-2.4 -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lgio-2.0 -lcairomm-1.0 -lcairo -lsigc-2.0 -lgdk_pixbuf-2.0 -lgobject-2.0 -lglib-2.0
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded. The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name. The directories searched include several standard system directories plus any that you specify with -L. Normally the files found this way are library files---archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with lib and .a and searches several directories.
Der Befehl:
pkg-config --cflags
erzeugt bei mir folgende Ausgabe:
-pthread -I/usr/include/gtkmm-3.0 -I/usr/lib/gtkmm-3.0/include -I/usr/include/atkmm-1.6 -I/usr/include/gtk-3.0/unix-print -I/usr/include/gdkmm-3.0 -I/usr/lib/gdkmm-3.0/include -I/usr/include/giomm-2.4 -I/usr/lib/giomm-2.4/include -I/usr/include/pangomm-1.4 -I/usr/lib/pangomm-1.4/include -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/cairomm-1.0 -I/usr/lib/cairomm-1.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/harfbuzz -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
Zitat aus der man-Page von g++:
Somit Stellt die Option -I die Möglichkeit dar ein Verzeichnis zu benennen, in dem sich die Header einer Bibliothek befinden.
Um ein einfaches Fenster zu erzeugen muss zunächst immer folgendes Grundgerüst erstellt werden:
#include <gtk/gtk.h> int main (int argc, char* argv[]) { gtk_init(&argc, &argv); GtkWidget *window; // *eventuelle *weitere *Widgets window = gtk_window_new(GTK_WINDOWTOPLEVEL); g_signal_connect(window,"delte-event",G_CALLBACK(gtk_main_quit),NULL); // Einbetten der weiteren Steuerelemente gtk_widget_show_all(window); // Damit das Fenster offen bleibt, bis es geschlossen wird gtk_main(); return 0 }
Dies ist der entsprechende Header für die Verwendung der GTK-Bibliothek
int main( int argc, char* argv[]){ ... }
Die Parameterübernahme in den Klammern ist für die GTK-Programmierung wesentlich. In der Folge wird auf diese Parameter zugegriffen.
Damit wird das UI initialisiert. Dadurch erhält zum Beispiel, das Fenster vom Standard her immer den Programmnamen, der unter anderm über diese Parameter übergeben wird.
GtkWidget window, weiter Variablen-Liste der Steuerelemente;
Alle Steuerelemente werden als GtkWidget-Variabeln deklariert, wobei jeder Widget-Variable ein Sternchen vorgesetzt wird.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
mit = gtk_window_new werden die Fenster definiert. Der Funktion muss als Parameter die Classe des Fensters übergeben werden. Für das Hauptprogrammfenster ist dies GTK_WINDOW_TOPLEVEL
g_signal_connect(window,"delete-event",G_CALLBACK(gtk_main_quit),NULL);
Um ein Ereignis zu empfangen, wird die Funktion g_signal_connect() genutzt. Diese hat 4 Parameter:
Einbetten weiterer Steuerelemente
Wichtig: Ein Fenster kann als Kontainer maximal ein Steuerelement aufnehmen. Deshalb muss dem Fenster zunächst ein Container zugeordnet werden, der die weiteren Steuerelemente aufnimmt, wenn mann mehr als ein Steuerelement anzeigen möchte!
Zum Einbetten weiterer Steuerelmente werden für diese zunächst Variablen deklariert und definiert. Die Deklaration ( GtkWidget widgetVariable;) kann auch direkt als mit Komma getrennte Liste, bei der Deklaration der Fenster-Widget-Variable erfolgen. Die Definiton erfolgt nach folgendem Schema:
widgetVariable = gtk_STEUERELEMENTNAME_new(Parameter);
Bsp. LABEL: lblEinLabel = gtk_label_new("Hallo Welt");
Dannach muss das Steuerelement einem Kontainer zugeordnet werden, indem es angezeigt werden soll. Dies geschiet im einfachsten Fall mit der Funktion: gtk_container_add(KONTAINER,STEUERELEMENTVARIABLE). Der Kontainer wird dabei über die Funktion GTK_CONTAINER(VARIABLE-DES-KONTAINERSTEUERELEMENTES) übergeben.
Bsp. LABEL: GtKWidget fEinFenster, *lblEinLabel; gtk_container_add(GTK_CONTAINER(fEinFenster),lblEinLabel);
Da das Widget window nur ein Steuerelement aufnehmen kann gibt es andere Container, die in window aufgenommen werden und Ihrerseits mehrere Steuerelemente aufnehmen können.
gtk_box_new(Orientierung, Abstand)
Orientierung kann sein:
Der Abstand wird in Pixel angegeben und bewirkt, dass alle Steuerelemente, die in die Box aufgenommen werden, diesen Abstand zueinander einhalten. Zum Rand der Box, wird hierdurch kein Abstand errzeugt.
Standardmäßig verwenden die Steuerelemente innerhalb der Box den gesamten Platz für alle Steuerelemente in der Richtung in der die Box ausgerichtet ist, nicht aber in der jeweils andern. Das heist bei einer Horizontalen Ausrichtung, dass sich die Steuerelemente unabhängig von Ihren benötigten Platz über die gesammte Breite ausdehnen, in der Höhe allerdings nur den tatsächlich benötigten Platz beanspruchen und der restliche zur Verfügung stehende Bereich frei bleibt. Möchte man die Ausdehnung auch in der jeweils anderen Richtung einschalten, nutzt man die Funktion: gtk_box_set_homogeneous(GtkBox *box, gboolean homogeneous); Bsp: Wenn die Box box heißt: gtk_box_set_homogeneous(GTK_BOX(box),true);
Anstatt die Steuerelemente mit der gtk_container_add Funktion einer Box zuzuordnen und so ein Standard-Layout zu bekommen, bietet die gtk_box_pack_start() bzw gtk_box_pack_end() Funktion mehr Möglichkeiten.
Beide Funktionen haben folgende Parameter:
GtkWidget win, *box, *lblEinLabel; ... lblEinLabel = gtk_label_new("Text, der angezeigt werden soll"); gtk_container_add(GTK_CONTAINER(box),lblEinLabel); ...
gtk_label_set_text(Label,Text);
Setzt den als Zeichenkette angegbenen Text für das Label. Das Label wird durch die Funktion GTK_LABEL(label-Widget-Variable) übergeben.
Beispiel: gtk_label_set_text(GTK_LABEL(lblEinLabel),"Das soll angezeigt werden");
GtkWidget win, *box, *btnEinButton; btnEinButton = gtk_button_new(); // Button als leerer Kontainer besser: btnEinButton = gtk_button_new_with_label("Button-Text"); gtk_container_add(GTK_CONTAINER(box),btnEinButton);
static void element_Ereignis(GtkWidget* widget, gpointer data) { // Ausgabe in der Konsole g_print("Es ist etwas passiert\n"); }
Zum Anzeigen des Fensters und aller dazugehörigen Elemente.
Ist der Loop, der das Fenster geöffnet hält, bis es durch den Benutzer oder das Programm geschlossen wird.
Der Abschluss der main-Funktion. Das Zurückgeben von 0 zeigt an, dass das Prtogramm ordnungsgemäß beendet wurde.