gtkmm Beispiel Programm Pt. 2
-
Bei diesem Beispiel zeige ich euch eine Möglichkeit Boxes zuverwenden.
Boxes sind Widget-( Komponenten ) Container die mindestens 1 Objekt aufnehmen. Gtk+ und somit auch gtkmm ist nach dem Boxen prinzip aufgebaut, ein Fenster (z.B Gtk::Window) kann nur 1 Objekt aufnehmen, aber da ein Fenster meist aus vielen Objekten besteht, kann man dort z.b. ein VBox einfügen und somit dann beliebig viele sub elemente mit vertikaler Anordnung hinzufügen, oder mit einem HBox in Horizontaler Anordnung.Es gibt auch ein Table das eben eine Tabelle für solche boxen bereitstellt, aber auf das komm ich später mal.
#include <gtkmm.h> // Bindet alles was man für gtkmm braucht ein (Braucht dann alles auch länger beim kompilieren
struct MyWindow : public Gtk::Window { MyWindow(); // Konstruktor Gtk::Button m_ok_button; // Button Objekt, wegen der Initialisierungsliste das erste Objekt! Gtk::Entry m_edit; // Ein Editfeld bzw Entry Gtk::Label m_labels[2]; // 2 Labels / Textfelder enum { MW_Label1 , MW_Label2 }; // Index ersatz für unser Label Array void on_button_ok_clicked(); // Funktion die beim Clicked-Signal des Buttons ausgeführt wird };
Es gibt in Gtk+/gtkmm so genannte Stockitems das sind Bilder und Texte die sich an die aktuellen Style Einstellungen anpassen und an das aktuelle locale
Wir benutzen für unseren Button einfach mal das Standard OK, und machen das folgendermaßen, in der Initialisierungsliste des Konstruktors. Da Elemente der Reihenfolge nach in der Intialisierungsliste aufgeführt werden müssen haben wir auch in der Deklaration den Button als erstes angegeben.
MyWindow::MyWindow() : m_ok_button(Gtk::Stock::OK) {
set_title(Glib::locale_to_utf8("gtkmm Beispiel 2")); // Setzen des Fenstertitels Gtk::VBox * vbox = new Gtk::VBox; // Wir erstellen eine Vertikale Box für unsere widgets add(*Gtk::manage(vbox)); // Wir übergeben die VBox an unser Fenster und sorgen dafür das es automatisch gelöscht wird vbox->set_homogeneous(true); // für gleichmässigkeit sorgen vbox->set_spacing( 10 ); // Platzzwischen den Elementen des VBoxes vbox->set_border_width( 10 ); // Randbreite auf 10 Pixel setzen vbox->pack_start( m_labels[ MW_Label1 ],true,true); // Wir fügen das erste Label in den ersten Abschnitt des vbox ein Gtk::HBox * hbox = new Gtk::HBox; // Neues Box objekt ( Horizontal (wer hätte das gedacht ? ;) ) ) vbox->pack_start( *Gtk::manage( hbox )); // Nun übergeben wir das HBox und sorgen, wie wir das beim VBox auch getan haben dafür dass user Objekt automatisch gelöscht wird hbox->pack_start( m_labels[ MW_Label2 ] ); // Nun fügen wir das 2te Label noch hinzu hbox->pack_start( m_edit ); // Nun noch das Editfeld / Entry hbox->set_spacing( 15 ); vbox->pack_start( m_ok_button ); // Und den natürlich dann den button Button // Nun setzen wir den Text der Labels m_labels[MW_Label1].set_text(Glib::locale_to_utf8("Gib nen Text ein und klick OK!")); m_labels[MW_Label2].set_text(Glib::locale_to_utf8("Text eingeben: ")); // Wir setzen die Callback Methode für das click signal m_ok_button.signal_clicked().connect( sigc::mem_fun(*this,&MyWindow::on_button_ok_clicked)); // Alle Widgets anzeigen show_all(); } void MyWindow::on_button_ok_clicked() { // Wir lesen den Text vom Entry und übergeben diesen an das Label m_labels[MW_Label1].set_text( m_edit.get_text()); }
So und zu guter letzt das ganze Programm incl. main()
#include <gtkmm.h> struct MyWindow : public Gtk::Window { MyWindow(); Gtk::Button m_ok_button; Gtk::Entry m_edit; Gtk::Label m_labels[2]; enum { MW_Label1 , MW_Label2 }; void on_button_ok_clicked(); }; int main(int argc, char**argv) { Gtk::Main main_obj(argc,argv); MyWindow window_obj; main_obj.run(window_obj); return EXIT_SUCCESS; } MyWindow::MyWindow() : m_ok_button(Gtk::Stock::OK) { set_title(Glib::locale_to_utf8("gtkmm Beispiel 2")); Gtk::VBox * vbox = new Gtk::VBox; add(*Gtk::manage(vbox)); vbox->set_homogeneous(true); vbox->set_spacing( 10 ); vbox->set_border_width( 10 ); vbox->pack_start( m_labels[ MW_Label1 ],true,true); Gtk::HBox * hbox = new Gtk::HBox; vbox->pack_start( *Gtk::manage( hbox )); hbox->pack_start( m_labels[ MW_Label2 ] ); hbox->pack_start( m_edit ); hbox->set_spacing( 15 ); vbox->pack_start( m_ok_button ); m_labels[MW_Label1].set_text(Glib::locale_to_utf8("Gib nen Text ein und klick OK!")); m_labels[MW_Label2].set_text(Glib::locale_to_utf8("Text eingeben: ")); m_ok_button.signal_clicked().connect( sigc::mem_fun(*this,&MyWindow::on_button_ok_clicked)); show_all(); } void MyWindow::on_button_ok_clicked() { m_labels[MW_Label1].set_text( m_edit.get_text()); }
Fragen,Anregungen und/oder Verbesserungsvorschläge erwünscht !
MfG until next part
PS: Hier geht es 1. nicht um den Codingstyle und 2. auch nicht um die möglichst kürzeste lösung, wollt ich nur mal anmerken!
-
Hier noch einmal das gleiche in einer reduzierten Form. mit 41 Zeilen
#include <gtkmm.h> struct MyWindow : public Gtk::Window { MyWindow(); Gtk::Button m_ok_button; Gtk::VBox m_vbox; Gtk::HBox m_hbox; Gtk::Entry m_edit; Gtk::Label m_labels[2]; enum { MW_Label1 , MW_Label2 }; void on_button_ok_clicked(); }; int main(int argc, char**argv) { Gtk::Main main_obj(argc,argv); MyWindow window_obj; main_obj.run(window_obj); return EXIT_SUCCESS; } MyWindow::MyWindow() : m_ok_button(Gtk::Stock::OK), m_vbox(true , 10), m_hbox(false , 15) { set_title(Glib::locale_to_utf8("gtkmm Beispiel 2")); add(m_vbox); m_vbox.set_border_width( 10 ); m_vbox.pack_start( m_labels[ MW_Label1 ],true,true); m_vbox.pack_start( m_hbox ); m_hbox.pack_start( m_labels[ MW_Label2 ] ); m_hbox.pack_start( m_edit ); m_vbox.pack_start( m_ok_button ); m_labels[MW_Label1].set_text(Glib::locale_to_utf8("Gib nen Text ein und klick OK!")); m_labels[MW_Label2].set_text(Glib::locale_to_utf8("Text eingeben: ")); m_ok_button.signal_clicked().connect( sigc::mem_fun(*this,&MyWindow::on_button_ok_clicked)); show_all(); } void MyWindow::on_button_ok_clicked() { m_labels[MW_Label1].set_text( m_edit.get_text()); }
-
eViLiSSiMo schrieb:
PS: Hier geht es 1. nicht um den Codingstyle
Das stimmt zwar einerseits, aber andererseits passiert mir bei GUI-Code immer genau das: der Code wird häßlich.
Ist es also generell so: GUI-Code muß häßlich sein?
Oder kann man das auch schön machen? Wenn ja, dann wäre es schön, wenn Du auch das zeigen könntest. Gehört nämlich irgendwie schon dazu. Außerdem denke ich, daß viele Leute Schwierigkeiten haben ihre GUI Code-mäßig sauber zu strukturieren.
Btw.: Schönes "Tutorial"
-
Also viel besser als das so zumachen, geht es kaum. ( Zumindest nicht ohne libglademm )
#include <gtkmm.h> struct MyWindow : public Gtk::Window { MyWindow(); void on_button_ok_clicked(); private: // Widgets Gtk::Button m_ok_button; Gtk::VBox m_vbox; Gtk::HBox m_hbox; Gtk::Entry m_edit; Gtk::Label m_labels[2]; enum { MW_Label1 , MW_Label2 }; // Setup Methoden void setup_vbox(); void setup_hbox(); void set_label_text( unsigned label , Glib::ustring const & text , bool to_utf8 = false ); }; int main(int argc, char**argv) { Gtk::Main main_obj(argc,argv); MyWindow window_obj; main_obj.run(window_obj); return EXIT_SUCCESS; } MyWindow::MyWindow() : m_ok_button(Gtk::Stock::OK), m_vbox(true , 10), m_hbox(false , 15) { set_title(Glib::locale_to_utf8("gtkmm Beispiel 2")); setup_vbox(); setup_hbox(); m_ok_button.signal_clicked().connect( sigc::mem_fun(*this,&MyWindow::on_button_ok_clicked)); show_all(); } void MyWindow::on_button_ok_clicked() { set_label_text( MW_Label1 , m_edit.get_text()); } void MyWindow::setup_vbox() { add(m_vbox); m_vbox.set_border_width( 10 ); m_vbox.pack_start( m_labels[ MW_Label1 ],true,true); set_label_text(MW_Label1,"Gib nen Text ein und klick OK!",true); m_vbox.pack_start( m_hbox ); m_vbox.pack_start( m_ok_button ); } void MyWindow::setup_hbox() { m_hbox.pack_start( m_labels[ MW_Label2 ] ); m_hbox.pack_start( m_edit ); set_label_text(MW_Label2,"Text eingeben: ",true); } void MyWindow::set_label_text( unsigned label , Glib::ustring const & text , bool to_utf8 ) { if(to_utf8) m_labels[label].set_text(text); else m_labels[label].set_text(Glib::locale_to_utf8(text)); }
BR