ein Kapitel zurück                                           ein Kapitel weiter

Nun wollen wir uns die Wigets ansehen, mit den wir einen eigenen Texteditor erstellen könnten. GtkText stellt uns diese Widgets zur Verfügung. Und außerdem wollen wir uns ansehen, wie wir den Text weiter editieren können (GtkEditable).

Zuerst wollen wir also eine Text Widget erzeugen. Dies können sie mit der Funktion:

GtkWidget *gtk_text_new(GtkAdjustment *hadj, GtkAdjustment *vadj);  

Als Parameter übergeben sie das Adjustment für die horizontale und vertikale Scrollbar. Wollen sie das Adjustment nachträglich eintragen oder verändern dann macht man dies mit:

void gtk_text_set_adjustments(GtkText *text,GtkAdjustment *hadj, GtkAdjustment *vadj);  

Es muss noch angemerkt werden, das unser Text Widget keine horizontale Scrollbar unterstützt. Diese müssen sie selbst erzeugen mit gtk_vscrollbar_new.

Als nächstes müssen sie angeben ob das Textfeld bearbeitet (editiert) werden darf oder nicht. Dies legen wir mit der Funktion....

void gtk_text_set_editable(GtkText *text, gboolen editable);  

Setzen sie den Parameter editable auf TRUE, kann ein Text damit verarbeitet werden. Mit FALSE haben sie keinen Zugriff auf das Textfeld.

Wollen wir uns doch schon mal ein kleines Beispiel dazu ansehen:

/*Download:gtktex1.c*/

#include <gtk/gtk.h>

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



int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *box;
 GtkWidget *text;
 GtkWidget *button_quit, *button, *button2;

 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/

 button_quit  = gtk_button_new_with_label("Ende");


 text = gtk_text_new(NULL, NULL);
 gtk_text_set_editable(GTK_TEXT(text),TRUE);
 /*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);


 /*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), text, FALSE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), button_quit, FALSE, FALSE, 10);


 gtk_container_add(GTK_CONTAINER(fenster),box);

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

 gtk_main();

 return 0;
}

Und so könnte es aussehen:




An diesem Beispiel können sie schon erkennen, dass die Wörter am Zeilenende gebrochen werden. Vermeiden können sie dies mit der Funktion:

void gtk_set_word_wrap(GtkText *text, gboolen wrap);  

Wenn sie für den Parameter wrap TRUE eingeben, werden die Worte nicht mehr einfach abgezwackt, sondern fangen in der neuen Zeile an. Mit FALSE erreichen sie wieder die Default-Einstellung. Für unser Programm würde dies so aussehen:

 gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);  

Wollen sie das die Zeile nicht gebrochen wird am Ende, können sie die Funktion:

void gtk_text_set_line_wrap(GtkText *text, gboolen wrap);  

verwenden. Wenn sie FALSE eingeben werden die Zeilen nicht gebrochen. Dann müssen sie aber eine horizontale Scrollbar eingerichtet haben, da sich sonst der Text außer Ihrer Sichtbarkeit fortsetzt. Mit TRUE stellen sie alles wieder zum Default-Zustand.

Wollen sie die Position des Textes abfragen bzw setzen dann mit:

void gtk_text_set_point(GtkText *text, guint index); /*setzen*/
guint gtk_text_get_point(GtkText *text);             /*abfragen*/  

Die Länge des Textes können sie mit der Funktion:

quint gtk_text_get_length(GtkText *text);  

ermitteln. Wollen sie schon einen vorgegeben Text eingeben, dann mit folgender Funktion:

void gtk_text_insert(GtkText *text, GdkFont *font, GdkColor *fore,
                     GdkColor *back, const gchar *chars, gint length);  

Somit fügen sie ins Text Widget length Zeichen mit dem Inhalt von chars und dem Vordergrund von fore und dem Hintergrund von back mit der Schriftart font ein.

Diese Funktion verwenden wir zum Beispiel zum Einlesen von Dateien in den Texteditor. Hierzu ein Programmbeispiel. Ich gehen vorerst auf die Gdk-Elemente nicht ein und setzen dafür NULL ein.

Sie können das Programm in der Kommandozeile öffnen um eine andere Datei einzulesen mit:

programmname datei_zum_lesen  

Besser wäre es natürlich mit einer Entry-Box oder ähnlichem. Hier geht es aber nur zur Demonstration der Funktion gtk_text_insert. Hier der Quellcode:

/*Download:gtktex2.c*/

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

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

/*Gibt aktuelle Textlänge auf Konsole aus*/
void text_length_cb(GtkWidget* widget, gpointer data)
{
 guint length = gtk_text_get_length(GTK_TEXT(widget));
 g_print("Aktuelle Textlänge : %d\n",length);
}



int main(int argc, char **argv)
{
 GtkWidget *fenster;
 GtkWidget *box, *box2;
 GtkWidget *text;
 GtkWidget *button_quit, *button, *button2;
 FILE *f;
 char file[255];
 int is_file, nchar;

 if(argc == 2)
  {
   f = fopen(argv[1], "r");
   if(NULL == f)
    is_file = 0;
   else
    is_file = 1;
  }

 /*Gtk initialisieren*/
 gtk_init(&argc, &argv);
 /*Ein neues Fenster erstellen*/
 fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 /*Buttons erstellen*/
 gtk_window_set_default_size(GTK_WINDOW(fenster), 320, 300);

 button_quit  = gtk_button_new_with_label("Ende");
 button = gtk_button_new_with_label("Textlänge");

 text = gtk_text_new(NULL, NULL);
 gtk_text_set_editable(GTK_TEXT(text),TRUE);
 gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);

 /*Neue Box erstellen*/
 box = gtk_vbox_new(FALSE,0);
 box2= gtk_hbox_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_object(GTK_OBJECT(button), "clicked",
                    GTK_SIGNAL_FUNC(text_length_cb), GTK_OBJECT(text));


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

 if(is_file)
   {
     while (1)
      {
        nchar = fread(file, 1, 255, f);
        gtk_text_insert (GTK_TEXT (text), NULL, NULL,
                         NULL, file, nchar);

        if (nchar < 255)
          break;
      }
   }

 gtk_container_set_border_width(GTK_CONTAINER(fenster),15);

 gtk_box_pack_start(GTK_BOX(box), text, TRUE, TRUE, 10);
 gtk_box_pack_start(GTK_BOX(box2), button_quit, TRUE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box2), button, TRUE, FALSE, 0);
 gtk_box_pack_start(GTK_BOX(box), box2, FALSE, FALSE, 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:




Weiter nützliche Funktionen wären:

qint gtk_text_foreward_delete(GtkText *text, gint nchars);
gint gtk_text_backward_delete(GtkText *text, gint nchars);  

Damit werden von der aktuellen Position nchar Zeichen im Text vorwärts bzw. rückwärts gelöscht.

Wollen sie den Text für die weiter Bearbeitung Sperren:

void gtk_text_freeze(GtkText *text);  

Aufheben können sie dies mit der Funktion:

void gtk_text_thaw(GtkText *text);  

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf