[X] GTKmm Tutorial Teil 3



  • Grafische Benutzerschnittstellen in C++ mit GTKmm Betriebssystemunabhängig gestalten Teil 3

    In diesem Teil werde ich Gtk::Entry, Gtk::SpinButton, Gtk::Statusbar und Gtk::ProgressBar vorstellen. Zu den Widgets gibts meistens nicht viel zu erzählen und der Code erklärt mehr als langes gerede.
    Schaut euch die Beispiele an und ihr werdet verstehen wie das ganze funktioniert. (Hoffe ich mal :p) So und nun geht es auch schon los.

    1. Gtk::Entry
    Das Gtk::Entry Widget kennen die meisten eher unter Edit. Hierbei handelt es sich um ein einfaches, einzeiliges Eingabefeld.

    Ein Verwendungsbeispiel:

    #include <gtkmm.h>
    
    struct EntryTutorial : Gtk::Window
    {
        EntryTutorial();
    private:
        Gtk::Entry  m_entry;
        Gtk::Button m_button;
        Gtk::HBox   m_hbox;
    
        void on_entry_changed();
    };
    
    EntryTutorial::EntryTutorial()
    : Gtk::Window(), 
      m_entry(),
      m_button(Gtk::Stock::QUIT),
      m_hbox(true,10)
    {
        // Gtk::Entry als erstes 
        m_hbox.pack_start(m_entry);
    
        // Button als zweites 
        m_hbox.pack_start(m_button);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse, damit kann man dann die anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Das Signal wird nach jedem zeichen aufgerufen das entweder eingegeben oder gelöscht wurde!
        // Damit kann man super eingaben überprüfen und evtl bestimmte Zeichen blocken :)
        m_entry.signal_changed().connect(sigc::mem_fun(*this,&EntryTutorial::on_entry_changed));
    
        show_all_children();
    }
    
    void EntryTutorial::on_entry_changed()
    {
        // Da ich hier ein Umlaut verwenden möchte und der String UTF-8 ist, 
        // kodiere ich das 'ä' hier von Hand als 0xC3A4
        Glib::ustring msg = "Der Text des Entrys hat sich ge\xC3\xA4ndert. Neuer Text: ";
    
        // Den Text der im Entry eingegeben wurde an unsere Nachricht anhängen
        msg += m_entry.get_text();
    
        Gtk::MessageDialog dia(*this,msg);
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        EntryTutorial window;
        main.run(window);
        return 0;
    }
    

    2. Gtk::SpinButton

    Bei einem Gtk::SpinButton handelt es sich um ein Eingabefeld für numerische Werte mit einem Up/Down Widget. (Siehe Screenshot unterhalb des codes ;))

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct SpinButtonTutorial : Gtk::Window
    {
        SpinButtonTutorial();
    private:
        Gtk::Adjustment m_spin_button_adjustment;
        Gtk::SpinButton m_spin_button;
        Gtk::Button     m_button;
        Gtk::HBox       m_hbox;
        int             m_previous_value;
        void on_spinbutton_value_changed();
    };
    
    SpinButtonTutorial::SpinButtonTutorial()
    : Gtk::Window(), 
      m_spin_button_adjustment(6,1,12,1,6,0),// value = 6, lower = 1, upper = 12, step_inc = 1, page_inc = 6, pagesize = 0
      m_spin_button(m_spin_button_adjustment),// SpinButton mit den Randbedingungen initialisieren
      m_button(Gtk::Stock::QUIT), // Stockbutton wie gehabt ;)
      m_hbox(false,10),
      m_previous_value(0)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Gtk::SpinButton als erstes 
        m_hbox.pack_start(m_spin_button,Gtk::PACK_SHRINK);
    
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Button als zweites 
        m_hbox.pack_start(m_button);
    
        // 10 px rand um die Horizontale Box
        m_hbox.set_border_width(10);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse, damit kann man dann die anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        m_spin_button.signal_value_changed().connect(sigc::mem_fun(*this,&SpinButtonTutorial::on_spinbutton_value_changed));
    
        show_all_children();
    }
    
    void SpinButtonTutorial::on_spinbutton_value_changed()
    {
        // Ich benutze hier Boost.Format um meinen String zu erzeugen.
        // Da Glib::ustring einen operator std::string() hat und man somit 
        // in der Lage ist das Glib::ustring objekt wie ein std::string zu benutzen
        Glib::ustring msg = "Wert hat sich von %1% zu %2% ge\xC3\xA4ndert."; 
    
        boost::format fmt(msg);
    
        // Den alten und den aktuellen Wert an das boost::format objekt übergeben
        // damit der String erzeugt werden kann
        fmt % m_previous_value % m_spin_button.get_value_as_int();
    
        // Nun speichere ich den neuen Wert damit wir den das nächste mal zur 
        // Verfügung haben
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Message Dialog wie gehabt ;)
        Gtk::MessageDialog dia(*this,fmt.str());
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        SpinButtonTutorial window;
        main.run(window);
        return 0;
    }
    

    3. Gtk::ProgressBar

    Ein ProgressBar kann man vertikal oder horizontal verwenden. Ich habe beides in diesem Code untergebracht.

    Desweiteren gibt es 2 Möglichkeiten eine ProgressBar zubenutzen. Entweder man benutzt es um den Fortschritt anzuzeigen um damit die aktuelle Prozentzahl des Fortschritts anzuzeigen. Oder man benutzt es mit pulse() um nur anzuzeigen das es Aktiv ist.

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct ProgressBarTutorial : Gtk::Window
    {
        ProgressBarTutorial();
    private:
    
        Gtk::VBox        m_vbox1;
        Gtk::VBox        m_vbox2;
        Gtk::HBox        m_hbox;
    
        Gtk::ProgressBar m_progressbar_h;
        Gtk::ProgressBar m_progressbar_v;
    
        Gtk::Button      m_button;
    
        bool on_activity_step();
        bool on_progress_step();
    };
    
    ProgressBarTutorial::ProgressBarTutorial()
    : Gtk::Window(),
      m_vbox1(),
      m_vbox2(),
      m_hbox(),
      m_progressbar_h(),
      m_progressbar_v(),
      m_button(Gtk::Stock::QUIT)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Wir möchten ein vertikales ProgressBar
        m_progressbar_v.set_orientation(Gtk::PROGRESS_BOTTOM_TO_TOP);
    
        // Aktuellen Fortschritt des horizontalen ProgressBar auf 0 setzen
        m_progressbar_h.set_fraction(0);
    
        // Abhier die übliche Anordnung der Widgets
        m_hbox.pack_start(m_progressbar_v,Gtk::PACK_SHRINK);
        m_hbox.set_spacing(10);
        m_vbox2.pack_start(m_progressbar_h,Gtk::PACK_EXPAND_PADDING);
    
        m_hbox.pack_start(m_vbox2);
    
        m_vbox1.pack_start(m_hbox);
        m_vbox1.pack_start(m_button,Gtk::PACK_SHRINK);
    
        m_vbox1.set_spacing(10);
        m_vbox1.set_border_width(10);
    
        add(m_vbox1);
    
        // Signale verbinden    
        // In diesen Fall verwenden wir hier eine Möglichkeit um Threads zu vermeiden
        // Normalerweise würde man für dieses Beispiel wohl 2 Threads starten 
        // Wir verwenden einfach eine andere Möglichkeit
        // Hierfür bietet die glib das Signal "timeout" 
        // Das nimmt mehrere SignalHandler auf und löst diese dann nach n angegebenen Millisekunden aus
    Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_activity_step),500);
        Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_progress_step),1000);    
    
        // Signal um das Fenster zuschließen(=> Beenden) verbinden 
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Alle Widgets anzeigen
        show_all_children();
    }
    
    bool ProgressBarTutorial::on_activity_step()
    {
        // Nächsten Pulse-Schritt ausführen
        m_progressbar_v.pulse();
    
        // Wir geben true zurück weil wir möchten das dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    bool ProgressBarTutorial::on_progress_step()
    {
        // Wir holen uns die aktuelle Prozentzahl und addieren 0.1 (als Schritt)
        // hinzu
        double cur = m_progressbar_h.get_fraction() + 0.1;
        // Prüfen ob 1.0 oder mehr erreicht wurden (Wenn ja zurücksetzen auf 0)
        if(cur >= 1.0)
            cur = 0;
        // Neuen Fortschrittstand setzen
        m_progressbar_h.set_fraction(cur);
        // Prozentanzeige (Text im Hintergrund des ProgressBar) setzen
        boost::format fmt("%i %%");
        fmt % (cur * 100);
        m_progressbar_h.set_text(fmt.str());
    
        // Wir geben true zurück weil wir möchten das dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        ProgressBarTutorial window;
        main.run(window);
        return 0;
    }
    

    4. Gtk::StatusBar

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct StatusBarTutorial : Gtk::Window
    {
        StatusBarTutorial();
        ~StatusBarTutorial();
    private:
        void on_button_push_clicked();
        void on_button_pop_clicked();
    private:
        Gtk::VBox m_vbox;
        Gtk::HBox m_hbox;
        Gtk::Button m_button_push;
        Gtk::Button m_button_pop;
        Gtk::Statusbar m_statusbar;
        unsigned m_context_id;
    };
    
    StatusBarTutorial::StatusBarTutorial()
    : m_vbox(false,12),
      m_button_push("Push"), 
      m_button_pop("Pop"),
      m_statusbar(),
      m_context_id(0)
    {
        m_hbox.pack_start(m_button_push);
    
        m_hbox.pack_start(m_button_pop);
    
        m_vbox.pack_start(m_hbox,Gtk::PACK_EXPAND_PADDING);
    
        // Ich würde, immer wenn ihr eine Statusbar verwendet
        // diesen eine VBox packen und dann mit Gtk::PACK_SHRINK
        // in das VBox Objekt packen, damit die Statusbar auch wie eine 
        // Statusbar aussieht ^^ Sonst ist es etwas sehr verschoben ;)
        m_vbox.pack_start(m_statusbar,Gtk::PACK_SHRINK);
    
        m_button_push.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_push_clicked));
    
        m_button_pop.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_pop_clicked));
    
        add(m_vbox);
    
        show_all_children();
    }
    
    StatusBarTutorial::~StatusBarTutorial()
    {   
    }
    
    void StatusBarTutorial::on_button_push_clicked()
    {   
        static unsigned count = 0;
        boost::format fmt("Text Nr %i");
        fmt % count++;
        // text auf den statusbar stack setzen
        m_statusbar.push(fmt.str());
    }
    
    void StatusBarTutorial::on_button_pop_clicked()
    {
        // Obersten Text vom Statusbar stack entfernen
        m_statusbar.pop();
    }
    
    int main(int argc, char ** argv)
    {
        Gtk::Main main(argc,argv);
        StatusBarTutorial window;
        main.run(window);
        return EXIT_SUCCESS;
    }
    

    Dieses mal war es extrem viel Code mit Kommentaren ich hoffe das es trotzdem Verständlich genug war, denn ich denke das man mehr vom praktischen lernt als vom Theoretischen gefasel 😉

    Solltet Ihr Fragen haben, einfach raus damit.

    So bis zum nächsten Teil 🙂

    Vinzenz 'evilissimo' Feenstra



  • An die Korrekturleser: Bitte beachtet auch alle Kommentare. Vielen Dank 🙂

    BR
    Vinzenz 😉

    //Edit: Korrektur :p



  • Grafische Benutzerschnittstellen in C++ mit GTKmm betriebssystemunabhängig gestalten Teil 3

    In diesem Teil werde ich Gtk::Entry, Gtk::SpinButton, Gtk::Statusbar und Gtk::ProgressBar vorstellen. Zu den Widgets gibts meistens nicht viel zu erzählen und der Code erklärt mehr als langes Gerede.
    Schaut euch die Beispiele an und ihr werdet verstehen, wie das ganze funktioniert (foffe ich mal :p). So und nun geht es auch schon los.

    1. Gtk::Entry
    Das Gtk::Entry Widget kennen die meisten eher unter Edit. Hierbei handelt es sich um ein einfaches, einzeiliges Eingabefeld.

    Ein Verwendungsbeispiel:

    #include <gtkmm.h>
    
    struct EntryTutorial : Gtk::Window
    {
        EntryTutorial();
    private:
        Gtk::Entry  m_entry;
        Gtk::Button m_button;
        Gtk::HBox   m_hbox;
    
        void on_entry_changed();
    };
    
    EntryTutorial::EntryTutorial()
    : Gtk::Window(), 
      m_entry(),
      m_button(Gtk::Stock::QUIT),
      m_hbox(true,10)
    {
        // Gtk::Entry als Erstes 
        m_hbox.pack_start(m_entry);
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Das Signal wird nach jedem Zeichen aufgerufen, das entweder eingegeben oder gelöscht wurde!
        // Damit kann man super Eingaben überprüfen und evtl. bestimmte Zeichen blocken :)
        m_entry.signal_changed().connect(sigc::mem_fun(*this,&EntryTutorial::on_entry_changed));
    
        show_all_children();
    }
    
    void EntryTutorial::on_entry_changed()
    {
        // Da ich hier ein Umlaut verwenden möchte und der String UTF-8 ist, 
        // kodiere ich das 'ä' hier von Hand als 0xC3A4
        Glib::ustring msg = "Der Text des Entrys hat sich ge\xC3\xA4ndert. Neuer Text: ";
    
        // Den Text, der im Entry eingegeben wurde, an unsere Nachricht anhängen
        msg += m_entry.get_text();
    
        Gtk::MessageDialog dia(*this,msg);
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        EntryTutorial window;
        main.run(window);
        return 0;
    }
    

    2. Gtk::SpinButton

    Bei einem Gtk::SpinButton handelt es sich um ein Eingabefeld für numerische Werte mit einem Up/Down Widget (siehe Screenshot unterhalb des Codes ;)).

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct SpinButtonTutorial : Gtk::Window
    {
        SpinButtonTutorial();
    private:
        Gtk::Adjustment m_spin_button_adjustment;
        Gtk::SpinButton m_spin_button;
        Gtk::Button     m_button;
        Gtk::HBox       m_hbox;
        int             m_previous_value;
        void on_spinbutton_value_changed();
    };
    
    SpinButtonTutorial::SpinButtonTutorial()
    : Gtk::Window(), 
      m_spin_button_adjustment(6,1,12,1,6,0),// value = 6, lower = 1, upper = 12, step_inc = 1, page_inc = 6, pagesize = 0
      m_spin_button(m_spin_button_adjustment),// SpinButton mit den Randbedingungen initialisieren
      m_button(Gtk::Stock::QUIT), // Stockbutton wie gehabt ;)
      m_hbox(false,10),
      m_previous_value(0)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Gtk::SpinButton als Erstes 
        m_hbox.pack_start(m_spin_button,Gtk::PACK_SHRINK);
    
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // 10 px Rand um die Horizontale Box
        m_hbox.set_border_width(10);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        m_spin_button.signal_value_changed().connect(sigc::mem_fun(*this,&SpinButtonTutorial::on_spinbutton_value_changed));
    
        show_all_children();
    }
    
    void SpinButtonTutorial::on_spinbutton_value_changed()
    {
        // Ich benutze hier Boost.Format, um meinen String zu erzeugen.
        // Da Glib::ustring einen Pperator std::string() hat und man somit 
        // in der Lage ist, das Glib::ustring objekt wie ein std::string zu benutzen
        Glib::ustring msg = "Wert hat sich von %1% zu %2% ge\xC3\xA4ndert."; 
    
        boost::format fmt(msg);
    
        // Den alten und den aktuellen Wert an das boost::format Objekt übergeben,
        // damit der String erzeugt werden kann
        fmt % m_previous_value % m_spin_button.get_value_as_int();
    
        // Nun speichere ich den neuen Wert, damit wir den das nächste Mal zur 
        // Verfügung haben
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Message Dialog wie gehabt ;)
        Gtk::MessageDialog dia(*this,fmt.str());
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        SpinButtonTutorial window;
        main.run(window);
        return 0;
    }
    

    3. Gtk::ProgressBar

    Eine ProgressBar kann man vertikal oder horizontal verwenden. Ich habe beides in diesem Code untergebracht.

    Des Weiteren gibt es zwei Möglichkeiten, eine ProgressBar zu benutzen. Entweder man benutzt sie, um den Fortschritt anzuzeigen, um damit die aktuelle Prozentzahl des Fortschritts anzuzeige, oder man benutzt sie mit pulse(), um nur anzuzeigen, dass es aktiv ist.

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct ProgressBarTutorial : Gtk::Window
    {
        ProgressBarTutorial();
    private:
    
        Gtk::VBox        m_vbox1;
        Gtk::VBox        m_vbox2;
        Gtk::HBox        m_hbox;
    
        Gtk::ProgressBar m_progressbar_h;
        Gtk::ProgressBar m_progressbar_v;
    
        Gtk::Button      m_button;
    
        bool on_activity_step();
        bool on_progress_step();
    };
    
    ProgressBarTutorial::ProgressBarTutorial()
    : Gtk::Window(),
      m_vbox1(),
      m_vbox2(),
      m_hbox(),
      m_progressbar_h(),
      m_progressbar_v(),
      m_button(Gtk::Stock::QUIT)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Wir möchten eine vertikale ProgressBar
        m_progressbar_v.set_orientation(Gtk::PROGRESS_BOTTOM_TO_TOP);
    
        // Aktuellen Fortschritt der horizontalen ProgressBar auf 0 setzen
        m_progressbar_h.set_fraction(0);
    
        // Ab hier die übliche Anordnung der Widgets
        m_hbox.pack_start(m_progressbar_v,Gtk::PACK_SHRINK);
        m_hbox.set_spacing(10);
        m_vbox2.pack_start(m_progressbar_h,Gtk::PACK_EXPAND_PADDING);
    
        m_hbox.pack_start(m_vbox2);
    
        m_vbox1.pack_start(m_hbox);
        m_vbox1.pack_start(m_button,Gtk::PACK_SHRINK);
    
        m_vbox1.set_spacing(10);
        m_vbox1.set_border_width(10);
    
        add(m_vbox1);
    
        // Signale verbinden    
        // In diesem Falle verwenden wir hier eine Möglichkeit, um Threads zu vermeiden
        // Normalerweise würde man für dieses Beispiel wohl zwei Threads starten 
        // Wir verwenden einfach eine andere Möglichkeit
        // Hierfür bietet die glib das Signal "timeout" 
        // Das nimmt mehrere SignalHandler auf und löst diese dann nach n angegebenen Millisekunden aus
    Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_activity_step),500);
        Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_progress_step),1000);    
    
        // Signal verbinden, um das Fenster zu schließen(=> Beenden)
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Alle Widgets anzeigen
        show_all_children();
    }
    
    bool ProgressBarTutorial::on_activity_step()
    {
        // Nächsten Pulse-Schritt ausführen
        m_progressbar_v.pulse();
    
        // Wir geben true zurück, weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    bool ProgressBarTutorial::on_progress_step()
    {
        // Wir holen uns die aktuelle Prozentzahl und addieren 0.1 (als Schritt)
        // hinzu
        double cur = m_progressbar_h.get_fraction() + 0.1;
        // Prüfen, ob 1.0 oder mehr erreicht wurden (wenn ja: zurücksetzen auf 0)
        if(cur >= 1.0)
            cur = 0;
        // Neuen Fortschrittstand setzen
        m_progressbar_h.set_fraction(cur);
        // Prozentanzeige (Text im Hintergrund der ProgressBar) setzen
        boost::format fmt("%i %%");
        fmt % (cur * 100);
        m_progressbar_h.set_text(fmt.str());
    
        // Wir geben true zurück ,weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        ProgressBarTutorial window;
        main.run(window);
        return 0;
    }
    

    4. Gtk::StatusBar

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct StatusBarTutorial : Gtk::Window
    {
        StatusBarTutorial();
        ~StatusBarTutorial();
    private:
        void on_button_push_clicked();
        void on_button_pop_clicked();
    private:
        Gtk::VBox m_vbox;
        Gtk::HBox m_hbox;
        Gtk::Button m_button_push;
        Gtk::Button m_button_pop;
        Gtk::Statusbar m_statusbar;
        unsigned m_context_id;
    };
    
    StatusBarTutorial::StatusBarTutorial()
    : m_vbox(false,12),
      m_button_push("Push"), 
      m_button_pop("Pop"),
      m_statusbar(),
      m_context_id(0)
    {
        m_hbox.pack_start(m_button_push);
    
        m_hbox.pack_start(m_button_pop);
    
        m_vbox.pack_start(m_hbox,Gtk::PACK_EXPAND_PADDING);
    
        // Ich würde, immer wenn ihr eine Statusbar verwendet,
        // diese in eine VBox packen und dann mit Gtk::PACK_SHRINK
        // in das VBox Objekt packen, damit die Statusbar auch wie eine 
        // Statusbar aussieht ^^ 
        // Sonst ist es etwas sehr verschoben ;)
        m_vbox.pack_start(m_statusbar,Gtk::PACK_SHRINK);
    
        m_button_push.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_push_clicked));
    
        m_button_pop.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_pop_clicked));
    
        add(m_vbox);
    
        show_all_children();
    }
    
    StatusBarTutorial::~StatusBarTutorial()
    {   
    }
    
    void StatusBarTutorial::on_button_push_clicked()
    {   
        static unsigned count = 0;
        boost::format fmt("Text Nr %i");
        fmt % count++;
        // Text auf der statusbar stack setzen
        m_statusbar.push(fmt.str());
    }
    
    void StatusBarTutorial::on_button_pop_clicked()
    {
        // Obersten Text von der Statusbar stack entfernen
        m_statusbar.pop();
    }
    
    int main(int argc, char ** argv)
    {
        Gtk::Main main(argc,argv);
        StatusBarTutorial window;
        main.run(window);
        return EXIT_SUCCESS;
    }
    

    Dieses Mal war es extrem viel Code mit Kommentaren. Ich hoffe, dass es trotzdem verständlich genug war, denn ich denke, dass man mehr vom Praktischen lernt als vom theoretischen Gefasel 😉

    Solltet ihr Fragen haben, einfach raus damit.

    So, bis zum nächsten Teil 🙂

    Vinzenz 'evilissimo' Feenstra



  • Viele Probleme bei der Groß- und Kleinschreibung.
    Dann "dass" mit Doppel-S beachten! "Ich denke, dass..." usw.

    Ich habe mal ProgressBar und wie die alle hießen als feminin gesetzt!
    also...

    die ProgressBar, die StatusBar

    Mr. B



  • Mr. B schrieb:

    Viele Probleme bei der Groß- und Kleinschreibung.
    Dann "dass" mit Doppel-S beachten! "Ich denke, dass..." usw.

    Ich habe mal ProgressBar und wie die alle hießen als feminin gesetzt!
    also...

    die ProgressBar, die StatusBar

    Mr. B

    Danke. Das mit der Groß- und Kleinschreibung kommt vom chatten, da schreib ich fast nur klein egal ob es groß geschrieben wird oder auch nicht. *g*

    Und wenn es mir mal aufgefallen ist hab ich es groß geschrieben ^^

    Tja und das mit dem ", dass" ist bei mir so eine Sache ^^

    Auf jeden Fall vielen Dank fürs überprüfen.

    Regards,

    Vinzenz



  • Grafische Benutzerschnittstellen in C++ mit GTKmm betriebssystemunabhängig gestalten Teil 3

    In diesem Teil werde ich Gtk::Entry, Gtk::SpinButton, Gtk::Statusbar und Gtk::ProgressBar vorstellen. Zu den Widgets gibts meistens nicht viel zu erzählen und der Code erklärt mehr als langes Gerede.
    Schaut euch die Beispiele an und ihr werdet verstehen, wie das ganze funktioniert (hoffe ich mal :p). So und nun geht es auch schon los.

    1. Gtk::Entry
    Das Gtk::Entry Widget kennen die meisten eher unter Edit. Hierbei handelt es sich um ein einfaches, einzeiliges Eingabefeld.

    Ein Verwendungsbeispiel:

    #include <gtkmm.h>
    
    struct EntryTutorial : Gtk::Window
    {
        EntryTutorial();
    private:
        Gtk::Entry  m_entry;
        Gtk::Button m_button;
        Gtk::HBox   m_hbox;
    
        void on_entry_changed();
    };
    
    EntryTutorial::EntryTutorial()
    : Gtk::Window(), 
      m_entry(),
      m_button(Gtk::Stock::QUIT),
      m_hbox(true,10)
    {
        // Gtk::Entry als Erstes 
        m_hbox.pack_start(m_entry);
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Das Signal wird nach jedem Zeichen aufgerufen, das entweder eingegeben oder gelöscht wurde!
        // Damit kann man super Eingaben überprüfen und evtl. bestimmte Zeichen blocken :)
        m_entry.signal_changed().connect(sigc::mem_fun(*this,&EntryTutorial::on_entry_changed));
    
        show_all_children();
    }
    
    void EntryTutorial::on_entry_changed()
    {
        // Da ich hier ein Umlaut verwenden möchte und der String UTF-8 ist, 
        // kodiere ich das 'ä' hier von Hand als 0xC3A4
        Glib::ustring msg = "Der Text des Entries hat sich ge\xC3\xA4ndert. Neuer Text: ";
    
        // Den Text, der im Entry eingegeben wurde, an unsere Nachricht anhängen
        msg += m_entry.get_text();
    
        Gtk::MessageDialog dia(*this,msg);
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        EntryTutorial window;
        main.run(window);
        return 0;
    }
    

    2. Gtk::SpinButton

    Bei einem Gtk::SpinButton handelt es sich um ein Eingabefeld für numerische Werte mit einem Up/Down Widget (siehe Screenshot unterhalb des Codes ;)).

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct SpinButtonTutorial : Gtk::Window
    {
        SpinButtonTutorial();
    private:
        Gtk::Adjustment m_spin_button_adjustment;
        Gtk::SpinButton m_spin_button;
        Gtk::Button     m_button;
        Gtk::HBox       m_hbox;
        int             m_previous_value;
        void on_spinbutton_value_changed();
    };
    
    SpinButtonTutorial::SpinButtonTutorial()
    : Gtk::Window(), 
      m_spin_button_adjustment(6,1,12,1,6,0),// value = 6, lower = 1, upper = 12, step_inc = 1, page_inc = 6, pagesize = 0
      m_spin_button(m_spin_button_adjustment),// SpinButton mit den Randbedingungen initialisieren
      m_button(Gtk::Stock::QUIT), // Stockbutton wie gehabt ;)
      m_hbox(false,10),
      m_previous_value(0)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Gtk::SpinButton als Erstes 
        m_hbox.pack_start(m_spin_button,Gtk::PACK_SHRINK);
    
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // 10 px Rand um die Horizontale Box
        m_hbox.set_border_width(10);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        m_spin_button.signal_value_changed().connect(sigc::mem_fun(*this,&SpinButtonTutorial::on_spinbutton_value_changed));
    
        show_all_children();
    }
    
    void SpinButtonTutorial::on_spinbutton_value_changed()
    {
        // Ich benutze hier Boost.Format, um meinen String zu erzeugen.
        // Da Glib::ustring einen Pperator std::string() hat und man somit 
        // in der Lage ist, das Glib::ustring objekt wie ein std::string zu benutzen
        Glib::ustring msg = "Wert hat sich von %1% zu %2% ge\xC3\xA4ndert."; 
    
        boost::format fmt(msg);
    
        // Den alten und den aktuellen Wert an das boost::format Objekt übergeben,
        // damit der String erzeugt werden kann
        fmt % m_previous_value % m_spin_button.get_value_as_int();
    
        // Nun speichere ich den neuen Wert, damit wir den das nächste Mal zur 
        // Verfügung haben
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Message Dialog wie gehabt ;)
        Gtk::MessageDialog dia(*this,fmt.str());
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        SpinButtonTutorial window;
        main.run(window);
        return 0;
    }
    

    3. Gtk::ProgressBar

    Eine ProgressBar kann man vertikal oder horizontal verwenden. Ich habe beides in diesem Code untergebracht.

    Des Weiteren gibt es zwei Möglichkeiten, eine ProgressBar zu benutzen. Entweder man benutzt sie, um den Fortschritt anzuzeigen, um damit die aktuelle Prozentzahl des Fortschritts anzuzeigen, oder man benutzt sie mit pulse(), um nur anzuzeigen, dass es aktiv ist.

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct ProgressBarTutorial : Gtk::Window
    {
        ProgressBarTutorial();
    private:
    
        Gtk::VBox        m_vbox1;
        Gtk::VBox        m_vbox2;
        Gtk::HBox        m_hbox;
    
        Gtk::ProgressBar m_progressbar_h;
        Gtk::ProgressBar m_progressbar_v;
    
        Gtk::Button      m_button;
    
        bool on_activity_step();
        bool on_progress_step();
    };
    
    ProgressBarTutorial::ProgressBarTutorial()
    : Gtk::Window(),
      m_vbox1(),
      m_vbox2(),
      m_hbox(),
      m_progressbar_h(),
      m_progressbar_v(),
      m_button(Gtk::Stock::QUIT)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Wir möchten eine vertikale ProgressBar
        m_progressbar_v.set_orientation(Gtk::PROGRESS_BOTTOM_TO_TOP);
    
        // Aktuellen Fortschritt der horizontalen ProgressBar auf 0 setzen
        m_progressbar_h.set_fraction(0);
    
        // Ab hier die übliche Anordnung der Widgets
        m_hbox.pack_start(m_progressbar_v,Gtk::PACK_SHRINK);
        m_hbox.set_spacing(10);
        m_vbox2.pack_start(m_progressbar_h,Gtk::PACK_EXPAND_PADDING);
    
        m_hbox.pack_start(m_vbox2);
    
        m_vbox1.pack_start(m_hbox);
        m_vbox1.pack_start(m_button,Gtk::PACK_SHRINK);
    
        m_vbox1.set_spacing(10);
        m_vbox1.set_border_width(10);
    
        add(m_vbox1);
    
        // Signale verbinden    
        // In diesem Falle verwenden wir hier eine Möglichkeit, um Threads zu vermeiden
        // Normalerweise würde man für dieses Beispiel wohl zwei Threads starten 
        // Wir verwenden einfach eine andere Möglichkeit
        // Hierfür bietet die glib das Signal "timeout" 
        // Das nimmt mehrere SignalHandler auf und löst diese dann nach n angegebenen Millisekunden aus
    Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_activity_step),500);
        Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_progress_step),1000);    
    
        // Signal verbinden, um das Fenster zu schließen(=> Beenden)
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Alle Widgets anzeigen
        show_all_children();
    }
    
    bool ProgressBarTutorial::on_activity_step()
    {
        // Nächsten Pulse-Schritt ausführen
        m_progressbar_v.pulse();
    
        // Wir geben true zurück, weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    bool ProgressBarTutorial::on_progress_step()
    {
        // Wir holen uns die aktuelle Prozentzahl und addieren 0.1 (als Schritt)
        // hinzu
        double cur = m_progressbar_h.get_fraction() + 0.1;
        // Prüfen, ob 1.0 oder mehr erreicht wurden (wenn ja: zurücksetzen auf 0)
        if(cur >= 1.0)
            cur = 0;
        // Neuen Fortschrittstand setzen
        m_progressbar_h.set_fraction(cur);
        // Prozentanzeige (Text im Hintergrund der ProgressBar) setzen
        boost::format fmt("%i %%");
        fmt % (cur * 100);
        m_progressbar_h.set_text(fmt.str());
    
        // Wir geben true zurück ,weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        ProgressBarTutorial window;
        main.run(window);
        return 0;
    }
    

    4. Gtk::StatusBar

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct StatusBarTutorial : Gtk::Window
    {
        StatusBarTutorial();
        ~StatusBarTutorial();
    private:
        void on_button_push_clicked();
        void on_button_pop_clicked();
    private:
        Gtk::VBox m_vbox;
        Gtk::HBox m_hbox;
        Gtk::Button m_button_push;
        Gtk::Button m_button_pop;
        Gtk::Statusbar m_statusbar;
        unsigned m_context_id;
    };
    
    StatusBarTutorial::StatusBarTutorial()
    : m_vbox(false,12),
      m_button_push("Push"), 
      m_button_pop("Pop"),
      m_statusbar(),
      m_context_id(0)
    {
        m_hbox.pack_start(m_button_push);
    
        m_hbox.pack_start(m_button_pop);
    
        m_vbox.pack_start(m_hbox,Gtk::PACK_EXPAND_PADDING);
    
        // Ich würde, immer wenn ihr eine Statusbar verwendet,
        // diese in eine VBox packen und dann mit Gtk::PACK_SHRINK
        // in das VBox Objekt packen, damit die Statusbar auch wie eine 
        // Statusbar aussieht ^^ 
        // Sonst ist es etwas sehr verschoben ;)
        m_vbox.pack_start(m_statusbar,Gtk::PACK_SHRINK);
    
        m_button_push.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_push_clicked));
    
        m_button_pop.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_pop_clicked));
    
        add(m_vbox);
    
        show_all_children();
    }
    
    StatusBarTutorial::~StatusBarTutorial()
    {   
    }
    
    void StatusBarTutorial::on_button_push_clicked()
    {   
        static unsigned count = 0;
        boost::format fmt("Text Nr %i");
        fmt % count++;
        // Text auf der statusbar stack setzen
        m_statusbar.push(fmt.str());
    }
    
    void StatusBarTutorial::on_button_pop_clicked()
    {
        // Obersten Text von der Statusbar stack entfernen
        m_statusbar.pop();
    }
    
    int main(int argc, char ** argv)
    {
        Gtk::Main main(argc,argv);
        StatusBarTutorial window;
        main.run(window);
        return EXIT_SUCCESS;
    }
    

    Dieses Mal war es extrem viel Code mit Kommentaren. Ich hoffe, dass es trotzdem verständlich genug war, denn ich denke, dass man mehr vom Praktischen lernt als vom theoretischen Gefasel 😉

    Solltet ihr Fragen haben, einfach raus damit.

    So, bis zum nächsten Teil 🙂

    Vinzenz 'evilissimo' Feenstra



  • Hinter die Kapitelnummern kommen keine Punkte.
    Und dann bitte noch je eine Leerzeile unter die Überschriften.
    🙂



  • Grafische Benutzerschnittstellen in C++ mit GTKmm betriebssystemunabhängig gestalten Teil 3

    In diesem Teil werde ich Gtk::Entry, Gtk::SpinButton, Gtk::Statusbar und Gtk::ProgressBar vorstellen. Zu den Widgets gibts meistens nicht viel zu erzählen und der Code erklärt mehr als langes Gerede.
    Schaut euch die Beispiele an und ihr werdet verstehen, wie das ganze funktioniert (hoffe ich mal :p). So und nun geht es auch schon los.

    1 Gtk::Entry

    Das Gtk::Entry Widget kennen die meisten eher unter Edit. Hierbei handelt es sich um ein einfaches, einzeiliges Eingabefeld.

    Ein Verwendungsbeispiel:

    #include <gtkmm.h>
    
    struct EntryTutorial : Gtk::Window
    {
        EntryTutorial();
    private:
        Gtk::Entry  m_entry;
        Gtk::Button m_button;
        Gtk::HBox   m_hbox;
    
        void on_entry_changed();
    };
    
    EntryTutorial::EntryTutorial()
    : Gtk::Window(), 
      m_entry(),
      m_button(Gtk::Stock::QUIT),
      m_hbox(true,10)
    {
        // Gtk::Entry als Erstes 
        m_hbox.pack_start(m_entry);
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Das Signal wird nach jedem Zeichen aufgerufen, das entweder eingegeben oder gelöscht wurde!
        // Damit kann man super Eingaben überprüfen und evtl. bestimmte Zeichen blocken :)
        m_entry.signal_changed().connect(sigc::mem_fun(*this,&EntryTutorial::on_entry_changed));
    
        show_all_children();
    }
    
    void EntryTutorial::on_entry_changed()
    {
        // Da ich hier ein Umlaut verwenden möchte und der String UTF-8 ist, 
        // kodiere ich das 'ä' hier von Hand als 0xC3A4
        Glib::ustring msg = "Der Text des Entries hat sich ge\xC3\xA4ndert. Neuer Text: ";
    
        // Den Text, der im Entry eingegeben wurde, an unsere Nachricht anhängen
        msg += m_entry.get_text();
    
        Gtk::MessageDialog dia(*this,msg);
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        EntryTutorial window;
        main.run(window);
        return 0;
    }
    

    2 Gtk::SpinButton

    Bei einem Gtk::SpinButton handelt es sich um ein Eingabefeld für numerische Werte mit einem Up/Down Widget (siehe Screenshot unterhalb des Codes ;)).

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct SpinButtonTutorial : Gtk::Window
    {
        SpinButtonTutorial();
    private:
        Gtk::Adjustment m_spin_button_adjustment;
        Gtk::SpinButton m_spin_button;
        Gtk::Button     m_button;
        Gtk::HBox       m_hbox;
        int             m_previous_value;
        void on_spinbutton_value_changed();
    };
    
    SpinButtonTutorial::SpinButtonTutorial()
    : Gtk::Window(), 
      m_spin_button_adjustment(6,1,12,1,6,0),// value = 6, lower = 1, upper = 12, step_inc = 1, page_inc = 6, pagesize = 0
      m_spin_button(m_spin_button_adjustment),// SpinButton mit den Randbedingungen initialisieren
      m_button(Gtk::Stock::QUIT), // Stockbutton wie gehabt ;)
      m_hbox(false,10),
      m_previous_value(0)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Gtk::SpinButton als Erstes 
        m_hbox.pack_start(m_spin_button,Gtk::PACK_SHRINK);
    
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Button als Zweites 
        m_hbox.pack_start(m_button);
    
        // 10 px Rand um die Horizontale Box
        m_hbox.set_border_width(10);
    
        // HBox dem Fenster übergeben
        add(m_hbox);
    
        // Hier verbinden wir das clicked signal des Buttons mit der hide Methode 
        // der Gtk::Window Klasse. Damit kann man dann die Anwendung beenden
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        m_spin_button.signal_value_changed().connect(sigc::mem_fun(*this,&SpinButtonTutorial::on_spinbutton_value_changed));
    
        show_all_children();
    }
    
    void SpinButtonTutorial::on_spinbutton_value_changed()
    {
        // Ich benutze hier Boost.Format, um meinen String zu erzeugen.
        // Da Glib::ustring einen Pperator std::string() hat und man somit 
        // in der Lage ist, das Glib::ustring objekt wie ein std::string zu benutzen
        Glib::ustring msg = "Wert hat sich von %1% zu %2% ge\xC3\xA4ndert."; 
    
        boost::format fmt(msg);
    
        // Den alten und den aktuellen Wert an das boost::format Objekt übergeben,
        // damit der String erzeugt werden kann
        fmt % m_previous_value % m_spin_button.get_value_as_int();
    
        // Nun speichere ich den neuen Wert, damit wir den das nächste Mal zur 
        // Verfügung haben
        m_previous_value = m_spin_button.get_value_as_int();
    
        // Message Dialog wie gehabt ;)
        Gtk::MessageDialog dia(*this,fmt.str());
        dia.run();
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        SpinButtonTutorial window;
        main.run(window);
        return 0;
    }
    

    3 Gtk::ProgressBar

    Eine ProgressBar kann man vertikal oder horizontal verwenden. Ich habe beides in diesem Code untergebracht.

    Des Weiteren gibt es zwei Möglichkeiten, eine ProgressBar zu benutzen. Entweder man benutzt sie, um den Fortschritt anzuzeigen, um damit die aktuelle Prozentzahl des Fortschritts anzuzeigen, oder man benutzt sie mit pulse(), um nur anzuzeigen, dass es aktiv ist.

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct ProgressBarTutorial : Gtk::Window
    {
        ProgressBarTutorial();
    private:
    
        Gtk::VBox        m_vbox1;
        Gtk::VBox        m_vbox2;
        Gtk::HBox        m_hbox;
    
        Gtk::ProgressBar m_progressbar_h;
        Gtk::ProgressBar m_progressbar_v;
    
        Gtk::Button      m_button;
    
        bool on_activity_step();
        bool on_progress_step();
    };
    
    ProgressBarTutorial::ProgressBarTutorial()
    : Gtk::Window(),
      m_vbox1(),
      m_vbox2(),
      m_hbox(),
      m_progressbar_h(),
      m_progressbar_v(),
      m_button(Gtk::Stock::QUIT)
    {
        set_title("GTKmm Tutorial Teil 3");
    
        // Wir möchten eine vertikale ProgressBar
        m_progressbar_v.set_orientation(Gtk::PROGRESS_BOTTOM_TO_TOP);
    
        // Aktuellen Fortschritt der horizontalen ProgressBar auf 0 setzen
        m_progressbar_h.set_fraction(0);
    
        // Ab hier die übliche Anordnung der Widgets
        m_hbox.pack_start(m_progressbar_v,Gtk::PACK_SHRINK);
        m_hbox.set_spacing(10);
        m_vbox2.pack_start(m_progressbar_h,Gtk::PACK_EXPAND_PADDING);
    
        m_hbox.pack_start(m_vbox2);
    
        m_vbox1.pack_start(m_hbox);
        m_vbox1.pack_start(m_button,Gtk::PACK_SHRINK);
    
        m_vbox1.set_spacing(10);
        m_vbox1.set_border_width(10);
    
        add(m_vbox1);
    
        // Signale verbinden    
        // In diesem Falle verwenden wir hier eine Möglichkeit, um Threads zu vermeiden
        // Normalerweise würde man für dieses Beispiel wohl zwei Threads starten 
        // Wir verwenden einfach eine andere Möglichkeit
        // Hierfür bietet die glib das Signal "timeout" 
        // Das nimmt mehrere SignalHandler auf und löst diese dann nach n angegebenen Millisekunden aus
    Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_activity_step),500);
        Glib::signal_timeout().connect(sigc::mem_fun(*this,&ProgressBarTutorial::on_progress_step),1000);    
    
        // Signal verbinden, um das Fenster zu schließen(=> Beenden)
        m_button.signal_clicked().connect(sigc::mem_fun(*this,&Gtk::Window::hide));
    
        // Alle Widgets anzeigen
        show_all_children();
    }
    
    bool ProgressBarTutorial::on_activity_step()
    {
        // Nächsten Pulse-Schritt ausführen
        m_progressbar_v.pulse();
    
        // Wir geben true zurück, weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    bool ProgressBarTutorial::on_progress_step()
    {
        // Wir holen uns die aktuelle Prozentzahl und addieren 0.1 (als Schritt)
        // hinzu
        double cur = m_progressbar_h.get_fraction() + 0.1;
        // Prüfen, ob 1.0 oder mehr erreicht wurden (wenn ja: zurücksetzen auf 0)
        if(cur >= 1.0)
            cur = 0;
        // Neuen Fortschrittstand setzen
        m_progressbar_h.set_fraction(cur);
        // Prozentanzeige (Text im Hintergrund der ProgressBar) setzen
        boost::format fmt("%i %%");
        fmt % (cur * 100);
        m_progressbar_h.set_text(fmt.str());
    
        // Wir geben true zurück ,weil wir möchten, dass dieses timeout signal 
        // wieder aufgerufen wird
        return true;
    }
    
    int main(int argc, char **argv)
    {
        Gtk::Main main(argc,argv);
        ProgressBarTutorial window;
        main.run(window);
        return 0;
    }
    

    4 Gtk::StatusBar

    #include <gtkmm.h>
    #include <boost/format.hpp>
    
    struct StatusBarTutorial : Gtk::Window
    {
        StatusBarTutorial();
        ~StatusBarTutorial();
    private:
        void on_button_push_clicked();
        void on_button_pop_clicked();
    private:
        Gtk::VBox m_vbox;
        Gtk::HBox m_hbox;
        Gtk::Button m_button_push;
        Gtk::Button m_button_pop;
        Gtk::Statusbar m_statusbar;
        unsigned m_context_id;
    };
    
    StatusBarTutorial::StatusBarTutorial()
    : m_vbox(false,12),
      m_button_push("Push"), 
      m_button_pop("Pop"),
      m_statusbar(),
      m_context_id(0)
    {
        m_hbox.pack_start(m_button_push);
    
        m_hbox.pack_start(m_button_pop);
    
        m_vbox.pack_start(m_hbox,Gtk::PACK_EXPAND_PADDING);
    
        // Ich würde, immer wenn ihr eine Statusbar verwendet,
        // diese in eine VBox packen und dann mit Gtk::PACK_SHRINK
        // in das VBox Objekt packen, damit die Statusbar auch wie eine 
        // Statusbar aussieht ^^ 
        // Sonst ist es etwas sehr verschoben ;)
        m_vbox.pack_start(m_statusbar,Gtk::PACK_SHRINK);
    
        m_button_push.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_push_clicked));
    
        m_button_pop.signal_clicked()
            .connect(sigc::mem_fun(*this,&StatusBarTutorial::on_button_pop_clicked));
    
        add(m_vbox);
    
        show_all_children();
    }
    
    StatusBarTutorial::~StatusBarTutorial()
    {   
    }
    
    void StatusBarTutorial::on_button_push_clicked()
    {   
        static unsigned count = 0;
        boost::format fmt("Text Nr %i");
        fmt % count++;
        // Text auf der statusbar stack setzen
        m_statusbar.push(fmt.str());
    }
    
    void StatusBarTutorial::on_button_pop_clicked()
    {
        // Obersten Text von der Statusbar stack entfernen
        m_statusbar.pop();
    }
    
    int main(int argc, char ** argv)
    {
        Gtk::Main main(argc,argv);
        StatusBarTutorial window;
        main.run(window);
        return EXIT_SUCCESS;
    }
    

    Dieses Mal war es extrem viel Code mit Kommentaren. Ich hoffe, dass es trotzdem verständlich genug war, denn ich denke, dass man mehr vom Praktischen lernt als vom theoretischen Gefasel 😉

    Solltet ihr Fragen haben, einfach raus damit.

    So, bis zum nächsten Teil 🙂

    Vinzenz 'evilissimo' Feenstra



  • BR


Anmelden zum Antworten