[X] GTKmm Tutorial Teil 4
-
Grafische Benutzerschnittstellen in C++ mit GTKmm Betriebssystemunabhängig gestalten Teil 4
1 Gtk::ScrolledWindow
Ein Gtk::ScrolledWindow ist ein Widget Container der Scrollbalken für diverse Widgets anbietet. Meistens verwendet mandas Gtk::ScrolledWindow für Gtk::TreeView (bespreche ich in einem anderem Teil) und das TextView welches diesesmal das Hauptthema ist.
Selten, aber dennoch findet das Gtk::ScrolledWindow Verwendung für die Gtk::DrawingArea welche zum zeichnen verwendet wird. Ich werde auf die Gtk::DrawingArea in meinem Tutorial warscheinlich überhaupt nicht weiter zu sprechen kommen, sollte jemand interesse an diesem Widget haben da er selbst etwas zeichnen möchte empfehle ich diesem die GTKmm Dokumentationsseiten [1]
Die wichtigsten Methoden die man von Gtk::ScrolledWindow kennen sollte sind die Methode add() um ein Widget hinzuzufügen und set_policy(). set_policy() verwendet man um anzugeben wie sich die Scrollbalken verhalten sollen. Ob sie immer sichtbar sein sollen(Gtk::POLICY_ALWAYS), ob sie niemals sichtbar sein sollen(Gtk::POLICY_NEVER) oder ob sie automatisch angezeigt werden sollen wenn das Widget zu groß wird(Gtk::POLICY_AUTOMATIC).
Man kann das Verhalten je für den horizontalen und den vertikalen Scrollbalken festlegen.
Viel mehr muss man meines erachtens gar nicht über das Gtk::ScrolledWindow wissen. Deswegen höre ich hier mit dem Thema auf und komme gleich zum nächsten.
2 Gtk::TextView
Das Gtk::TextView bietet vielseitige Möglichkeiten um Text darstellen zu können, es ist aber auch möglich Bilder oder andere Widgets einzufügen. Aufgrund seiner Vielfältigkeit werde ich nur ein paar
grundlegende Features erklären.Grundsätzlich braucht man für ein Gtk::TextView 3 Dinge. Ein Gtk::ScrolledWindow, ein Gtk::TextBuffer und das Gtk::TextView selbst.
2.1 Simples TextView Beispiel
#include <gtkmm.h> struct TextViewTutorial : public Gtk::Window { TextViewTutorial(); ~TextViewTutorial(); private: Gtk::ScrolledWindow m_scrolled_window; Gtk::TextView m_textview; Glib::RefPtr<Gtk::TextBuffer> m_textbuffer; }; TextViewTutorial::TextViewTutorial() { // Fenstergröße setzen set_size_request(400,200); // Titel setzen set_title("GTKmm Tutorial Teil 4"); // Text Puffer erstellen m_textbuffer = Gtk::TextBuffer::create(); // Wir wollen das die Balken automatisch angezeigt werden wenn mehr Text // vorhanden ist als in den Anzeigebereich passt m_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); // Textpuffer setzen m_textview.set_buffer(m_textbuffer); // Textview dem Scrolled Window hinzufügen m_scrolled_window.add(m_textview); // ScrolledWindow dem Fenster hinzufügen add(m_scrolled_window); // Alle Widgets anzeigen show_all_children(); } TextViewTutorial::~TextViewTutorial() { } int main(int argc, char **argv) { Gtk::Main main(argc,argv); TextViewTutorial window; main.run(window); return EXIT_SUCCESS; }
2.2 Textformatierungen
Das anlegen eines Textviews ist sehr simpel wie man am obigen Beispiel gut erkennen kann.
Interessanter wird es wenn man Textformatieren möchte. Hierzu werden "Tags" definiert welche eine Formatierung des Textes definieren.
Man kann mehrere dieser Tags anlegen und mit namen versehen. Zusätzlich können mehrere Tags auf den gleichen Tags angewandt werden.Mit Tags kann man unter anderem folgende Formatierungen setzen:
- Schriftart
- Schriftgröße
- Hintergrundfarbe
- Textfarbe
- Textstil (wie z.B. Kursiv, Fett, Unterstrichen etc. mit diversen Abstufungen)
...Es gibt noch mehr Möglichkeiten welche am besten aus der Dokumentation zu ersehen sind.
Nun zu einem Beispiel wie man diese Tags verwendet.
#include <gtkmm.h> struct TextViewTutorial : public Gtk::Window { TextViewTutorial(); ~TextViewTutorial(); private: typedef Glib::RefPtr<Gtk::TextBuffer::Tag> TextTagPtr; Gtk::ScrolledWindow m_scrolled_window; Gtk::TextView m_textview; Glib::RefPtr<Gtk::TextBuffer> m_textbuffer; Gtk::HBox m_hbox; Gtk::VButtonBox m_vbuttonbox; Gtk::Button m_bold; Gtk::Button m_color; Gtk::Button m_underline; Gtk::Button m_italic; void apply_tag(TextTagPtr tag); void attach_signal(Gtk::Button & b, TextTagPtr const & tag); }; void TextViewTutorial::attach_signal(Gtk::Button & b, TextTagPtr const & tag) { b.signal_clicked().connect(sigc::bind<TextTagPtr>(sigc::mem_fun(this, &TextViewTutorial::apply_tag), tag)); } void TextViewTutorial::apply_tag(TextTagPtr tag) { Gtk::TextBuffer::iterator begin, end; if(m_textbuffer->get_selection_bounds(begin, end)) { m_textbuffer->apply_tag(tag, begin, end); } } TextViewTutorial::TextViewTutorial() { // Fenstergröße setzen set_size_request(400,200); // Titel setzen set_title("GTKmm Tutorial Teil 4 - Textformatierung"); // Text Puffer erstellen m_textbuffer = Gtk::TextBuffer::create(); // Wir wollen das die Balken automatisch angezeigt werden wenn mehr Text // vorhanden ist als in den Anzeigebereich passt m_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); // Textpuffer setzen m_textview.set_buffer(m_textbuffer); // Textview dem Scrolled Window hinzufügen m_scrolled_window.add(m_textview); //Erstellung der Tags und Definition der Formatierungen // Rote Schrift TextTagPtr color_tag = Gtk::TextBuffer::Tag::create("color"); color_tag->property_foreground() = "red"; // Fettschrift TextTagPtr bold_tag = Gtk::TextBuffer::Tag::create("bold"); bold_tag->property_weight() = 900; // Kursive Schrift TextTagPtr italic_tag = Gtk::TextBuffer::Tag::create("italic"); italic_tag->property_style() = Pango::STYLE_ITALIC; // Unterstrichener Text TextTagPtr underlined_tag = Gtk::TextBuffer::Tag::create("underlined"); underlined_tag->property_underline() = Pango::UNDERLINE_SINGLE; // Button Beschriftung setzen und signal verbinden m_color.set_label("Farbe"); attach_signal(m_color, color_tag); m_bold.set_label("Fett"); attach_signal(m_bold, bold_tag); m_italic.set_label("Kursiv"); attach_signal(m_italic, italic_tag); m_underline.set_label("Unterstrichen"); attach_signal(m_underline, underlined_tag); // Tags dem TextBuffer bekannt machen m_textbuffer->get_tag_table()->add(color_tag); m_textbuffer->get_tag_table()->add(bold_tag); m_textbuffer->get_tag_table()->add(italic_tag); m_textbuffer->get_tag_table()->add(underlined_tag); // Buttons der ButtonBox übergeben m_vbuttonbox.pack_start(m_color); m_vbuttonbox.pack_start(m_bold); m_vbuttonbox.pack_start(m_italic); m_vbuttonbox.pack_start(m_underline); // ScrolledWindow dem Layout hinzufügen m_hbox.pack_start(m_scrolled_window); // Button box dem Layout hinzufügen m_hbox.pack_start(m_vbuttonbox, Gtk::PACK_SHRINK, 10); // Layout setzen add(m_hbox); // Alle Widgets anzeigen show_all_children(); } TextViewTutorial::~TextViewTutorial() { } int main(int argc, char **argv) { Gtk::Main main(argc,argv); TextViewTutorial window; main.run(window); return EXIT_SUCCESS; }
Eine kleine Erklärung des Codes:
In diesem Beispiel werden vier Tags definiert "color", "bold", "italic" und "underlined". Diese vier Tags können mit dem Buttons gesetzt werden,
in dem man den eingegebenen Text auswählt und einen oder evtl auch mehrere Buttons anklickt.Nun noch eine erklärung der "attach_signal" Methode. Diese Methode setzt den Signalhandler für die übergebene Schaltfläche und bindet das übergebene Tag
an den Aufruf, somit kann man einen handler für alle buttons verwenden und muss nicht vier verschiedene schreiben.Die Methode apply_tag, welche durch einen Klick auf einen Button ausgelöst wird holt sich zunächst den Auswahlbereich über
if(m_textbuffer->get_selection_bounds(begin, end))
Sollte der Bereich leer sein, sprich wenn keine Auswahl vorhanden ist, gibt die Methode "get_selection_bounds" false zurück, andernfalls wird via
m_textbuffer->apply_tag(tag, begin, end);
das übergebene tag, auf den ausgewählten Bereich angewandt.
Und so siehts aus:
2.3 Weiterführendes zum Thema
Wenn ihr den Inhalt des TextView Puffers lesen oder ändern möchtet, wird dies mit Hilfe der Iteratoren erledigt.
Iteratoren sind aber nur gültig so lange der TextBuffer nicht verändert wurde.Manchmal möchte man sich aber eine bestimmte Position im Text merken, hierfür bietet GTK+ sogenannte TextMarks an, mit welchen man für eine bestimmte Stelle im Text ein "Lesezeichen" setzen kann.
Diese Lesezeichen können mit der Methode create_mark() erstellt werden.Glib::RefPtr<Gtk::TextBuffer::Mark> mark = m_textbuffer.create_mark(iterator_pos);
Man kann diese Lesezeichen auch benennen, damit kann man umgehen das man die Instanzen der Klasse TextMark herumreichen muss. Um ein benanntes Lesezeichen zu erstellen geht geht man wiefolgt vor:
Glib::RefPtr<Gtk::TextBuffer::Mark> mark = m_textbuffer.create_mark("LesezeichenName", iterator_pos);
Zusätzlich gibt es noch einen weiteren Parameter bei der Erstellung einer Textmarke "left_gravity" welcher per Voreinstellung auf true gesetzt ist.
Dieser Parameter gibt an in welche Richtung sich die Textmarke beim Einfügen vom Text verschiebt.Hinweis am Rande: Bei Sprachen die Recht-nach-Links gelesen werden ist left_gravity automatisch umgedreht, das heißt es verhält sich genauso zum Text wie bei den in Westlichen Ländern Verwendeten Eingabeschemata.
Es sind noch viel mehr Dinge mit Gtk::TextView möglich, welche aber den Rahmen eines Einsteiger Tutorials weit überschreiten würden.
Für nähere Infos zu diesem Thema schlagt einfach in der unten verlinkten Dokumentation nach um mehr zum Thema zu erfahren.Hier noch eine Kurze Zusammenfassung was man so alles damit anstellen kann:
- Ihr könnt mit der Zwischenablage arbeiten um Text auszulesen, schneiden, oder kopieren
- Ihr könnt Bilder und sogar andere Widgets wie Buttons, Checkboxen etc einfügen (z.b. um eine Webbrowser ähnliche Funktionalität zu erzeugen)
- Ihr habt unzählige Möglichkeiten zur Textformatierung, größe, dicke, Farbe, Ausrichtung u.v.mDas Interface zu der Funktionalität ist eigentlich für die Fülle der Möglichkeiten recht kompakt und
meines erachtens nach schnell zu verstehen, auch wenn einen die Methoden/Klassen die dazu gehören auf den ersten Blick erschlagen mögen.Ok ich hoffe Ihr hattet Spaß daran den Code zu lesen und ich hoffe es hat euch zu neuen Programmierideen inspiriert
Da ich momentan etwas Zeit habe werde ich mich auch gleich an den nächsten Teil machen damit Ihr auch bald wieder was zum Thema zu lesen habt!
Grüße aus der Tschechischen Republik,
Vinzenz 'evilissimo' Feenstra
Referenzen:
-
*push* damit die Lektoren den ja auch finden
BR,
Vinzenz
-
So, hier die korrigierte Fassung.
-----
Grafische Benutzerschnittstellen in C++ mit gtkmm betriebssystemunabhängig gestalten Teil 4
1 Gtk::ScrolledWindow
Ein Gtk::ScrolledWindow ist ein Container-Widget, welches Scrollbalken für diverse Widgets anbietet. Meistens verwendet man dass Gtk::ScrolledWindow für Gtk::TreeView (bespreche ich in einem anderem Teil) und das Gtk::TextView, welches dieses mal das Hauptthema ist.
Es kommt zwar selten vor, aber manchmal findet das Gtk::ScrolledWindow Verwendung für die Gtk::DrawingArea, welche zum Zeichnen verwendet wird. Ich werde auf die Gtk::DrawingArea in meinem Tutorial warscheinlich überhaupt nicht weiter zu sprechen kommen. Sollte jemand Interesse an diesem Widget haben, da er selbst etwas zeichnen möchte, empfehle ich diesem die gtkmm Dokumentationsseiten [1]
Die wichtigsten Methoden die man von Gtk::ScrolledWindow kennen sollte sind die Methode add(), um ein Widget hinzuzufügen und set_policy(). set_policy() verwendet man um anzugeben wie sich die Scrollbalken verhalten sollen. Ob sie immer sichtbar sein sollen (Gtk::POLICY_ALWAYS), ob sie niemals sichtbar sein sollen (Gtk::POLICY_NEVER) oder ob sie automatisch angezeigt werden sollen wenn das Widget zu groß wird (Gtk::POLICY_AUTOMATIC).
Man kann das Verhalten für den horizontalen und den vertikalen Scrollbalken festlegen.
Viel mehr muss man meines Erachtens gar nicht über das Gtk::ScrolledWindow wissen. Deswegen höre ich hier mit dem Thema auf und komme gleich zum Nächsten.
2 Gtk::TextView
Das Gtk::TextView bietet vielseitige Möglichkeiten um Text darstellen zu können, es ist aber auch möglich Bilder oder andere Widgets einzufügen. Aufgrund seiner Vielfältigkeit werde ich nur ein paar grundlegende Features erklären.
Grundsätzlich braucht man für ein Gtk::TextView drei Dinge: Ein Gtk::ScrolledWindow, ein Gtk::TextBuffer und das Gtk::TextView selbst.
2.1 Simples TextView Beispiel
#include <gtkmm.h> struct TextViewTutorial : public Gtk::Window { TextViewTutorial(); ~TextViewTutorial(); private: Gtk::ScrolledWindow m_scrolled_window; Gtk::TextView m_textview; Glib::RefPtr<Gtk::TextBuffer> m_textbuffer; }; TextViewTutorial::TextViewTutorial() { // Fenstergröße setzen set_size_request(400,200); // Titel setzen set_title("GTKmm Tutorial Teil 4"); // Textpuffer erstellen m_textbuffer = Gtk::TextBuffer::create(); // Wir wollen das die Balken automatisch angezeigt werden, sobald mehr Text // vorhanden ist als in den Anzeigebereich passt m_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); // Textpuffer setzen m_textview.set_buffer(m_textbuffer); // Textview dem ScrolledWindow hinzufügen m_scrolled_window.add(m_textview); // ScrolledWindow dem Fenster hinzufügen add(m_scrolled_window); // Alle Widgets anzeigen show_all_children(); } TextViewTutorial::~TextViewTutorial() { } int main(int argc, char **argv) { Gtk::Main main(argc,argv); TextViewTutorial window; main.run(window); return EXIT_SUCCESS; }
2.2 Textformatierungen
Wie man am obigen Beispiel gut erkennen kann, ist das Anlegen eines TextViews sehr simpel.
Interessanter wird es wenn man Text formatieren möchte. Hierzu werden "Tags" definiert, welche eine Formatierung des Textes definieren.
Man kann mehrere dieser Tags anlegen und mit Namen versehen. Zusätzlich können mehrere Tags auf den gleichen Text angewandt werden.Mit Tags kann man unter anderem folgende Formatierungen setzen:
- Schriftart
- Schriftgröße
- Hintergrundfarbe
- Textfarbe
- Textstil (wie z.B. Kursiv, Fett, Unterstrichen etc. mit diversen Abstufungen)
...Für noch mehr Möglichkeiten lohnt sich ein Blick in die Dokumentation.
Nun zu einem Beispiel, wie man diese Tags verwendet:
#include <gtkmm.h> struct TextViewTutorial : public Gtk::Window { TextViewTutorial(); ~TextViewTutorial(); private: typedef Glib::RefPtr<Gtk::TextBuffer::Tag> TextTagPtr; Gtk::ScrolledWindow m_scrolled_window; Gtk::TextView m_textview; Glib::RefPtr<Gtk::TextBuffer> m_textbuffer; Gtk::HBox m_hbox; Gtk::VButtonBox m_vbuttonbox; Gtk::Button m_bold; Gtk::Button m_color; Gtk::Button m_underline; Gtk::Button m_italic; void apply_tag(TextTagPtr tag); void attach_signal(Gtk::Button & b, TextTagPtr const & tag); }; void TextViewTutorial::attach_signal(Gtk::Button & b, TextTagPtr const & tag) { b.signal_clicked().connect(sigc::bind<TextTagPtr>(sigc::mem_fun(this, &TextViewTutorial::apply_tag), tag)); } void TextViewTutorial::apply_tag(TextTagPtr tag) { Gtk::TextBuffer::iterator begin, end; if(m_textbuffer->get_selection_bounds(begin, end)) { m_textbuffer->apply_tag(tag, begin, end); } } TextViewTutorial::TextViewTutorial() { // Fenstergröße setzen set_size_request(400,200); // Titel setzen set_title("GTKmm Tutorial Teil 4 - Textformatierung"); // Textpuffer erstellen m_textbuffer = Gtk::TextBuffer::create(); // Wir wollen das die Balken automatisch angezeigt werden, sobald mehr Text // vorhanden ist als in den Anzeigebereich passt m_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); // Textpuffer setzen m_textview.set_buffer(m_textbuffer); // Textview dem ScrolledWindow hinzufügen m_scrolled_window.add(m_textview); // Erstellung der Tags und Definition der Formatierungen // Rote Schrift TextTagPtr color_tag = Gtk::TextBuffer::Tag::create("color"); color_tag->property_foreground() = "red"; // Fettschrift TextTagPtr bold_tag = Gtk::TextBuffer::Tag::create("bold"); bold_tag->property_weight() = 900; // Kursive Schrift TextTagPtr italic_tag = Gtk::TextBuffer::Tag::create("italic"); italic_tag->property_style() = Pango::STYLE_ITALIC; // Unterstrichener Text TextTagPtr underlined_tag = Gtk::TextBuffer::Tag::create("underlined"); underlined_tag->property_underline() = Pango::UNDERLINE_SINGLE; // Buttonbeschriftung setzen und signal verbinden m_color.set_label("Farbe"); attach_signal(m_color, color_tag); m_bold.set_label("Fett"); attach_signal(m_bold, bold_tag); m_italic.set_label("Kursiv"); attach_signal(m_italic, italic_tag); m_underline.set_label("Unterstrichen"); attach_signal(m_underline, underlined_tag); // Tags dem TextPuffer bekannt machen m_textbuffer->get_tag_table()->add(color_tag); m_textbuffer->get_tag_table()->add(bold_tag); m_textbuffer->get_tag_table()->add(italic_tag); m_textbuffer->get_tag_table()->add(underlined_tag); // Buttons der ButtonBox übergeben m_vbuttonbox.pack_start(m_color); m_vbuttonbox.pack_start(m_bold); m_vbuttonbox.pack_start(m_italic); m_vbuttonbox.pack_start(m_underline); // ScrolledWindow dem Layout hinzufügen m_hbox.pack_start(m_scrolled_window); // Button box dem Layout hinzufügen m_hbox.pack_start(m_vbuttonbox, Gtk::PACK_SHRINK, 10); // Layout setzen add(m_hbox); // Alle Widgets anzeigen show_all_children(); } TextViewTutorial::~TextViewTutorial() { } int main(int argc, char **argv) { Gtk::Main main(argc,argv); TextViewTutorial window; main.run(window); return EXIT_SUCCESS; }
Eine kleine Erklärung des Codes:
In diesem Beispiel werden vier Tags definiert "color", "bold", "italic" und "underlined". Diese vier Tags können mit den Buttons gesetzt werden, indem man den eingegebenen Text auswählt und einen oder eventuell auch mehrere Buttons anklickt.Nun noch eine Erklärung der "attach_signal" Methode: Diese Methode setzt den Signalhandler für die übergebene Schaltfläche und bindet das übergebene Tag an den Aufruf, somit kann man einen Handler für alle Buttons verwenden und muss nicht vier verschiedene schreiben.
Die Methode "apply_tag", welche durch einen Klick auf einen Button ausgelöst wird, holt sich zunächst den Auswahlbereich über
if(m_textbuffer->get_selection_bounds(begin, end))
Sollte der Bereich leer sein, sprich wenn keine Auswahl vorhanden ist, gibt die Methode "get_selection_bounds" false zurück, andernfalls wird via
m_textbuffer->apply_tag(tag, begin, end);
das übergebene Tag auf den ausgewählten Bereich angewandt.
Und so sieht's aus:
2.3 Weiterführendes zum Thema
Wenn Ihr den Inhalt des TextView Puffers lesen oder ändern möchtet, wird dies mit Hilfe der Iteratoren erledigt. Iteratoren sind aber nur gültig solange der TextBuffer nicht verändert wurde.
Manchmal möchte man sich aber eine bestimmte Position im Text merken. Hierfür bietet gtkmm sogenannte TextMarks an, mit welchen man an einer bestimmten Stelle im Text ein "Lesezeichen" setzen kann. Diese Lesezeichen können mit der Methode create_mark() erstellt werden.
Glib::RefPtr<Gtk::TextBuffer::Mark> mark = m_textbuffer.create_mark(iterator_pos);
Man kann diese Lesezeichen auch benennen, damit kann man umgehen das man die Instanzen der Klasse TextMark herumreichen muss. Um ein benanntes Lesezeichen zu erstellen geht geht man folgenermaßen vor:
Glib::RefPtr<Gtk::TextBuffer::Mark> mark = m_textbuffer.create_mark("LesezeichenName", iterator_pos);
Zusätzlich gibt es noch einen weiteren Parameter bei der Erstellung einer Textmarke: "left_gravity", welcher per Voreinstellung auf true gesetzt ist.
Dieser Parameter gibt an, in welche Richtung sich die Textmarke beim Einfügen vom Text verschiebt.Hinweis am Rande: Bei Sprachen die Rechts-nach-Links gelesen werden ist "left_gravity" automatisch umgedreht, das heißt es verhält sich genauso zum Text wie bei den in westlichen Ländern verwendeten Eingabeschemata.
Es sind noch viel mehr Dinge mit Gtk::TextView möglich, jedoch würde dies den Rahmen eines Einsteiger Tutorials bei weitem überschreiten.
Für nähere Infos zu diesem Thema schlagt einfach in der unten verlinkten Dokumentation nach.Im Folgenden noch eine kurze Zusammenfassung, was man so alles mit einer Gtk::TextView anstellen kann:
- Ihr könnt mit der Zwischenablage arbeiten, um Text auszulesen, auszuschneiden, oder zu kopieren
- Ihr könnt Bilder und sogar andere Widgets wie Buttons, Checkboxen etc. einfügen (z.b. um eine einem Webbrowser ähnliche Funktionalität zu erzeugen)
- Ihr habt unzählige Möglichkeiten zur Textformatierung: Größe, Dicke, Farbe, Ausrichtung u.v.m.Das Interface zu der Funktionalität ist eigentlich für die Fülle der Möglichkeiten recht kompakt und meines Erachtens nach schnell zu verstehen, auch wenn einen die dazugehörigen Methoden/Klassen auf den ersten Blick erschlagen mögen.
Okay, ich hoffe Ihr hattet Spaß daran den Code zu lesen und ich hoffe es hat euch zu neuen Programmierideen inspiriert
Da ich momentan etwas Zeit habe, werde ich mich auch gleich an den nächsten Teil machen, damit Ihr auch bald wieder was zum Thema zu lesen habt!
Grüße aus der Tschechischen Republik,
Vinzenz 'evilissimo' Feenstra
Referenzen:
[1] GTKmm Dokumentationsseiten[/quote]
-
Ende :p
-
Dieser Thread wurde von Moderator/in estartu aus dem Forum Die Redaktion in das Forum Archiv verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.