Sehr Umfangreiche Webseite zum Programmieren in C Perl CGI, Skripting, Linux, Systemprogrammierung C C++ C/C++ ANSI C Linux Windows GUI gtk gtk+ Gimp Toolkit Widgets Callbacks Buttons GUI gtk gtk+ Gimp Toolkit Widgets Callbacks Buttons Buttons

Normale Buttons           zurück Ein Kapitel tiefer zum Inhaltsverzeichnis

Sie haben bereits gesehen, wie man einfache Buttons erstellen kann ...

GtkWidget *gtk_button_new(void); /*Button ohne Aufschrift*/

... oder ...

GtkWidget *gtk_button_new_with_label(const gchar *label);

Nun will man meistens schon wissen, welcher Button gedrückt wurde und wie man das feststellen kann. Sicherlich gibt es da einige Wege. Wir wollen hier einen davon verwenden. Hierzu ein simples Beispiel dazu ...

#include <gtk/gtk.h>
#include <gtk/gtkwidget.h>
#include <string.h>


void ende_cb(GtkObject *object)
{
 g_print("Und Tschüss!!\n");
 gtk_main_quit();
}


void check_button_press_cb(GtkWidget *widget, gpointer data)
{
 if(strcmp("Button 1", (char *)data) == 0)
   g_print("Button 1 wurde gedrückt\n");
 else if(strcmp("Button 2", (char *)data) == 0)
   g_print("Button 2 wurde gedrückt\n");
 else if(strcmp("Button 3", (char *)data) == 0)
   g_print("Button 3 wurde gedrückt\n");
 else if(strcmp("Button 4", (char *)data) == 0)
   g_print("Button 4 wurde gedrückt\n");
 else
   g_print("%s\n",(char *)data);
}



int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *button1, *button2, *button3, *button4;
 GtkWidget *table;
 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/
 button1  = gtk_button_new_with_label("Button 1");
 button2  = gtk_button_new_with_label("Button 2");
 button3  = gtk_button_new_with_label("Button 3");
 button4  = gtk_button_new_with_label("Button 4");

 /*Tabelle erstellen... 2x2*/
 table = gtk_table_new(2,2,FALSE);

 /*Signale registrieren*/
 gtk_signal_connect(GTK_OBJECT(fenster), "delete_event",
                    GTK_SIGNAL_FUNC(ende_cb), NULL);
 gtk_signal_connect(GTK_OBJECT(button1), "clicked",
                    GTK_SIGNAL_FUNC(check_button_press_cb),"Button 1" );
 gtk_signal_connect(GTK_OBJECT(button2), "clicked",
                    GTK_SIGNAL_FUNC(check_button_press_cb), "Button 2");
 gtk_signal_connect(GTK_OBJECT(button3), "clicked",
                    GTK_SIGNAL_FUNC(check_button_press_cb),"Button 3" );
 gtk_signal_connect(GTK_OBJECT(button4), "clicked",
                    GTK_SIGNAL_FUNC(check_button_press_cb), "Button 4");
 /*Fenstertitel*/
 gtk_window_set_title(GTK_WINDOW(fenster), "Welcher Button wurde gedrückt");
 /*Fensterposition*/
 gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER);

 gtk_container_set_border_width(GTK_CONTAINER(fenster),40);

 /*Inhalt der Tabelle mit verschiedenen Optionen erstellen....*/
 gtk_table_attach_defaults(GTK_TABLE(table), button1, 0,1, 0,1);
 gtk_table_attach_defaults(GTK_TABLE(table), button2, 0,1, 1,2);
 gtk_table_attach_defaults(GTK_TABLE(table), button3, 1,2, 0,1);
 gtk_table_attach_defaults(GTK_TABLE(table), button4, 1,2, 1,2);


 gtk_container_add(GTK_CONTAINER(fenster),table);

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

 gtk_main();

 return 0;
}

Bei diesem Beispiel wird jedes Button "clicked" auf der Konsole mit entsprechenden Button ausgegeben. Bitte verwenden Sie hierzu die Funktion g_print() anstatt printf(), da Sie sonst Probleme mit der Ausgabe haben werden, wegen der Pufferung von printf(). Natürlich wird in der Praxis nicht so reagiert. Sie könnten Beispielsweise eine neuen Prozess mit fork() erzeugen und ein anderes Programm aufrufen.

Sie können auch Theoretisch das Signal "clicked" für einen Button auslösen, ohne das wirklich ge"clicked" wurde. Dies bewerkstelligen Sie mit der Funktion ...

void gtk_button_clicked(GtkButton *button);

Ebenso können Sie mit den Funktionen ...

void gtk_button_pressed(GtkButton *button);
void gtk_button_enter(GtkButton *button);
void gtk_button_released(GtkButton *button);
void gtk_button_leave(GtkButton *button);

... weitere Events, also Signale senden.

Es ist auch möglich, dass aussehen Ihres Buttons zu beeinflussen. Dies wird mit folgender Funktion erledigt ...

void gtk_button_set_relief(GtkButton *button, GtkReliefStyle newstyle);

Damit hat der Button das Aussehen von newstyle, wofür Sie folgendes angeben können ...

Sie können dies ja bei dem Programmbeispiel oben testen ...

gtk_button_set_relief(GTK_BUTTON(button2), GTK_RELIEF_NONE);

... für den Button 2 zum Beispiel.

Wollen Sie aber zum Beispiel ein Jpeg oder Xpm-Bild auf dem Button anzeigen, benötigen Sie eine Funktion der gdk-Lib. Folgende Signale können Sie übrigens mit einem Button senden ...

Auch hier empfehle ich Ihnen mit den Events im Programm von oben herumzuspielen.

Toogle Buttons           zurück Ein Kapitel tiefer Ein Kapitel höher zum Inhaltsverzeichnis

Toggled Buttons sind im Prinzip nichts anderes als normale Buttons. Nur das Sie hier einen Knopf drücken und dieser gedrückt bleibt, bis Sie diesen Knopf erneut betätigen, oder auch umgekehrt. So wie Sie dies bei den Office Programmen mit der Schriftendarstellung wie Invers (I), Bold (B) oder Underline (U) kennen. Dies sind Toggled Buttons. Toggled Buttons stellen in GTK auch gleich die Basis für Checkbuttons oder Radiobuttons da.

Zuerst der Syntax wie Sie einen Toggled Button erstellen können ...

GtkWidget *gtk_toggle_button_new(void);

... oder mit Label ...

GtkWidget *gtk_toggle_button_new_with_label(gchar *label);

Der Umgang mit den Toggled Buttons ist der selbe wie mit den normalen Buttons. Um zu überprüfen ob ein Button ge"toggeld" oder nicht ge"toggeld" ist, verwendet man folgendes Makro ...

if(GTK_TOGGLE_BUTTON(widget)->active)
  { /*Button ist aktiviert*/ }
else
  { /*Button ist deaktiviert*/ }

Am besten wir sehen uns dazu ein einfaches Beispiel an ...

#include <gtk/gtk.h>

GtkWidget *button1, *button2, *button3, *button_quit;

void ende_cb(GtkObject *object)
{
  g_print("\n\nZustand der Toggled Buttons zum Abschluss : \n");
 if(GTK_TOGGLE_BUTTON(button1)->active)
   g_print("Knopf 1 war aktiviert (toggled)\n");
 else
   g_print("Knopf 1 war deaktiviert (not toggled)\n");

   g_print("Zustand der Toggled Buttons zum Abschluss : \n");
 if(GTK_TOGGLE_BUTTON(button2)->active)
   g_print("Knopf 2 war aktiviert (toggled)\n");
 else
   g_print("Knopf 2 war deaktiviert (not toggled)\n");

   g_print("Zustand der Toggled Buttons zum Abschluss : \n");
 if(GTK_TOGGLE_BUTTON(button3)->active)
   g_print("Knopf 3 war aktiviert (toggled)\n");
 else
   g_print("Knopf 3 war deaktiviert (not toggled)\n");


 gtk_main_quit();
}

void check_toggle_cb(GtkWidget *widget, gpointer data)
{
 if(GTK_TOGGLE_BUTTON(widget)->active)
   g_print("%s aktiviert (toggled)\n",(char *)data);
 else
   g_print("%s deaktiviert (not toggled)\n",(char *)data);
}

int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *box;
 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/
 button1  = gtk_toggle_button_new_with_label("Knopf 1");
 button2  = gtk_toggle_button_new_with_label("Knopf 2");
 button3  = gtk_toggle_button_new_with_label("Knopf 3");
 button_quit  = gtk_button_new_with_label("Ende");
 /*Neue Box erstellen*/
 box = gtk_vbox_new(FALSE,0);

 /*Signale registrieren*/
 gtk_signal_connect_object(GTK_OBJECT(button_quit), "clicked",
                           GTK_SIGNAL_FUNC(ende_cb), GTK_OBJECT(fenster));
 gtk_signal_connect(GTK_OBJECT(fenster), "destroy",
                    GTK_SIGNAL_FUNC(ende_cb), NULL);
 gtk_signal_connect(GTK_OBJECT(button1), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 1");
 gtk_signal_connect(GTK_OBJECT(button2), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 2");
 gtk_signal_connect(GTK_OBJECT(button3), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 3");
 /*Fenstertitel*/
 gtk_window_set_title(GTK_WINDOW(fenster), "Toggled Buttons");
 /*Fensterposition*/
 gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER);

 gtk_container_set_border_width(GTK_CONTAINER(fenster),25);

 /*Nun alles rein in die Box....*/
 gtk_box_pack_start(GTK_BOX(box), button1, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button2, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button3, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button_quit, FALSE, FALSE, 20);


 gtk_container_add(GTK_CONTAINER(fenster),box);

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

 gtk_main();

 return 0;
}

Das Programm überprüft auch den Buttonzustand bei Beendigung des Programms. So könnte es in etwas aussehen ...

Hier ist Beispielsweise "Knopf 2" aktiviert.

Hierzu noch weitere, nützliche, Funktion für unsere Toggle Buttons.

void gtk_toggle_button_set_mode(GtkToggleButton *t_button, gboolen draw);

Mit dieser Funktion können Sie einen Button unsichtbar machen. Dies geschieht mit dem Parameter draw. Default-Einstellung ist FALSE. Geben Sie stattdessen TRUE an, verschwindet der Button. So wird es verwendet ...

gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(button1), TRUE);

Sie können es ja im Programm oben einbauen. Hiermit würde der button1 nicht angezeigt.

Wollen Sie einen Buttonzustand setzen, oder abfragen, können Sie folgende Funktionen dazu benutzen ...

void gtk_toggle_button_set_mode(GtkToggleButton *t_button, gboolen how);

Mit dem Parameter how, können Sie den Button aktivieren (TRUE) oder wieder deaktiviere (FALSE). In der Praxis sieht dies so aus ...

gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),TRUE);

Das Gegenstück zu dieser Funktion lautet dann ...

gboolen gtk_toggle_button_get_mode(GtkToogleButton *t_button);

Diese Funktion liefert als Rückgabewert TRUE wenn der Button aktiviert ist. Ansonsten FALSE.

Checkbuttons und Radiobuttons           zurück Ein Kapitel tiefer zum Inhaltsverzeichnis

Checkbuttons und Radiobuttons funktionieren genauso wie die Toogled Buttons und verwenden auch die selben Funktionen. Nur eben bei der Erzeugen, werden andere Funktionen aufgerufen. Hier die Funktionen wie Sie Check Buttons erzeugen können ...

GtkWidget *gtk_check_button_new(void);

... oder mit einem Label ...

GtkWidget *gtk_check_button_new_with_label(gchar *label);

Hierzu das selben Programmbeispiel wie im Kapitel zuvor, den Toggled Buttons, nur eben mit Checkbuttons ...

#include <gtk/gtk.h>

GtkWidget *button1, *button2, *button3, *button_quit;

void ende_cb(GtkObject *object)
{
  g_print("\n\nZustand der Toggled Buttons zum Abschluss : \n");
 if(GTK_TOGGLE_BUTTON(button1)->active)
   g_print("Knopf 1 war aktiviert (toggled)\n");
 else
   g_print("Knopf 1 war deaktiviert (not toggled)\n");

 if(GTK_TOGGLE_BUTTON(button2)->active)
   g_print("Knopf 2 war aktiviert (toggled)\n");
 else
   g_print("Knopf 2 war deaktiviert (not toggled)\n");

 if(GTK_TOGGLE_BUTTON(button3)->active)
   g_print("Knopf 3 war aktiviert (toggled)\n");
 else
   g_print("Knopf 3 war deaktiviert (not toggled)\n");


 gtk_main_quit();
}

void check_toggle_cb(GtkWidget *widget, gpointer data)
{
 if(GTK_TOGGLE_BUTTON(widget)->active)
   g_print("%s aktiviert (toggled)\n",(char *)data);
 else
   g_print("%s deaktiviert (not toggled)\n",(char *)data);
}

int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *box;
 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/
 button1  = gtk_check_button_new_with_label("Knopf 1");
 button2  = gtk_check_button_new_with_label("Knopf 2");
 button3  = gtk_check_button_new_with_label("Knopf 3");
 button_quit  = gtk_button_new_with_label("Ende");
 /*Neue Box erstellen*/
 box = gtk_vbox_new(FALSE,0);

 /*Signale registrieren*/
 gtk_signal_connect_object(GTK_OBJECT(button_quit), "clicked",
                           GTK_SIGNAL_FUNC(ende_cb), GTK_OBJECT(fenster));
 gtk_signal_connect(GTK_OBJECT(fenster), "destroy",
                    GTK_SIGNAL_FUNC(ende_cb), NULL);
 gtk_signal_connect(GTK_OBJECT(button1), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 1");
 gtk_signal_connect(GTK_OBJECT(button2), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 2");
 gtk_signal_connect(GTK_OBJECT(button3), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 3");
 /*Fenstertitel*/
 gtk_window_set_title(GTK_WINDOW(fenster), "Toggled Buttons");
 /*Fensterposition*/
 gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER);

 gtk_container_set_border_width(GTK_CONTAINER(fenster),25);

 /*Nun alles rein in die Box....*/
 gtk_box_pack_start(GTK_BOX(box), button1, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button2, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button3, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button_quit, FALSE, FALSE, 20);

 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1),TRUE);

 gtk_container_add(GTK_CONTAINER(fenster),box);

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

 gtk_main();

 return 0;
}

Und so könnte es aussehen ...

Sie sehen, dass wir nur die Funktionen zum Erzeugen der Buttons geändert haben.

Radiobuttons
Ähnlich läuft dies auch mit Radio-Buttons ab. Hier die beiden Funktionen mit denen es möglich ist, Radio-Buttons zu erzeugen ...

GtkWidget *gtk_Radio_button_new(GSList  *group);

... oder mit einem Label ...

GtkWidget *gtk_check_button_new_with_label(GSList *group, gchar *label);

Natürlich läuft dies bei Radio-Buttons etwas anders ab. Ein Radio-Button ist auch ein Teil einer Gruppe von Knöpfen, wovon immer nur einer ausgewählt werden kann. Das heisst wenn Knopf 1 ausgewählt wurde und Sie wählen nun Knopf 2, wird Knopf 1 deaktiviert.

Daher ist es unbedingt nötig, nach dem Erzeugen einer neuen Gruppe von Radion-Buttons (welche mit NULL initialisiert werden müssen), die Funktion ...

GSList *gtk_radio_button_group(GtkRadioButton *radio_button);

... aufzurufen, da sich die Liste der Radio-Buttons ja geändert hat. Ansonsten gibt es keine Unterschiede zu den Toggled und Check Buttons. Standardmäßig ist immer der erste Radio-Button aktiviert. Aber ändern können Sie dies, wie schon bei den Toggled Buttons. Sehen wir uns doch einfach ein Beispiel dazu an ...

#include <gtk/gtk.h>

GtkWidget *button1, *button2, *button3, *button_quit;

void ende_cb(GtkObject *object)
{
  g_print("\n\nZustand der Toggled Buttons zum Abschluss : \n");
 if(GTK_TOGGLE_BUTTON(button1)->active)
   g_print("Knopf 1 war aktiviert (toggled)\n");
 else
   g_print("Knopf 1 war deaktiviert (not toggled)\n");

 if(GTK_TOGGLE_BUTTON(button2)->active)
   g_print("Knopf 2 war aktiviert (toggled)\n");
 else
   g_print("Knopf 2 war deaktiviert (not toggled)\n");

 if(GTK_TOGGLE_BUTTON(button3)->active)
   g_print("Knopf 3 war aktiviert (toggled)\n");
 else
   g_print("Knopf 3 war deaktiviert (not toggled)\n");


 gtk_main_quit();
}

void check_toggle_cb(GtkWidget *widget, gpointer data)
{
 if(GTK_TOGGLE_BUTTON(widget)->active)
   g_print("%s aktiviert (toggled)\n",(char *)data);
 else
   g_print("%s deaktiviert (not toggled)\n",(char *)data);
}

int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *box;
 GSList *r_group = NULL;
 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/
 button1  = gtk_radio_button_new_with_label(r_group,"Radio 1");
 r_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button1));
 button2  = gtk_radio_button_new_with_label(r_group,"Radio 2");
 r_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button2));
 button3  = gtk_radio_button_new_with_label(r_group,"Radio 3");
 r_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button3));
 button_quit  = gtk_button_new_with_label("Ende");
 /*Neue Box erstellen*/
 box = gtk_vbox_new(FALSE,0);

 /*Signale registrieren*/
 gtk_signal_connect_object(GTK_OBJECT(button_quit), "clicked",
                           GTK_SIGNAL_FUNC(ende_cb), GTK_OBJECT(fenster));
 gtk_signal_connect(GTK_OBJECT(fenster), "destroy",
                    GTK_SIGNAL_FUNC(ende_cb), NULL);
 gtk_signal_connect(GTK_OBJECT(button1), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 1");
 gtk_signal_connect(GTK_OBJECT(button2), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 2");
 gtk_signal_connect(GTK_OBJECT(button3), "clicked",
                    GTK_SIGNAL_FUNC(check_toggle_cb),"Knopf 3");
 /*Fenstertitel*/
 gtk_window_set_title(GTK_WINDOW(fenster), "Radio Buttons");
 /*Fensterposition*/
 gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER);

 gtk_container_set_border_width(GTK_CONTAINER(fenster),25);

 /*Nun alles rein in die Box....*/
 gtk_box_pack_start(GTK_BOX(box), button1, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button2, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button3, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button_quit, FALSE, FALSE, 20);

 /*Button 2 aktivieren*/
 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2),TRUE);

 gtk_container_add(GTK_CONTAINER(fenster),box);

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

 gtk_main();

 return 0;
}

Und so könnte es aussehen ...

Wollen Sie nachträglich einen Radio-Button zur Gruppe hinzuordnen, verwenden Sie die Funktion ...

void gtk_radio_button_set_group(GtkRadioButton *radio_button, GSList *group);

Weiter mit Horizontale Scrollbar