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


Anmelden zum Antworten