class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
};
#endif//GUARD_MY_WINDOW_HPP_INCLUDED
class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
};
#endif//GUARD_MY_WINDOW_HPP_INCLUDED
class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
};
#endif//GUARD_MY_WINDOW_HPP_INCLUDED
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
Dies mal hat sich etwas an der Eintritts-Funktion geändert:
main.cpp
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
Gtk::Main main_obj(argc,argv);
MyWindow window_obj;
main_obj.run(window_obj);
return EXIT_SUCCESS;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
Gtk::Main main_obj(argc,argv);
MyWindow window_obj;
main_obj.run(window_obj);
return EXIT_SUCCESS;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
class MyWindow : public Gtk::Window, boost::noncopyable
{
public:
MyWindow();
virtual ~MyWindow();
// on_button_click wird ausgeführt wenn der User den Button auf unserem
// Fenster anklickt void on_button_click();
// Diese Methode wird als seperater Thread gestartet
// Sie sorgt dann für die Animation des ProgressBar ohne die ganze Anwendung
// zu blockieren void thread_worker();
/* Das machen wir mit boost::noncopyable
private: // Nicht kopierbar!
MyWindow( MyWindow const & );
MyWindow const & operator=( MyWindow const & );
*/ private: // Deklaration der Variablen
// Diese Variable brauchen wir um das Ende des zweiten Threads
// zu veranlassen bool m_end_thread;
// Ich denke das ich mir zu diesen Widgets die Kommentare sparen kann
// da diese bereits in den Examples I und II bereits benutzt worden ist
Gtk::VBox m_vbox;
Gtk::Button m_button;
Gtk::Label m_label;
// ProgressBar zeigt an wie weit ein Prozess bereits ist
// Ausserdem hat sie die pulse eigenschaft, die anzeigt das etwas getan
// wird. Diese Pulse eigenschaft werden wir jetz einmal benutzen da
// sie imho die interessantere ist ;)
Gtk::ProgressBar m_pbar;
// Da wir eine Multi Threaded Anwendung schreiben müssen wird eine
// Möglichkeit finden wie wir problemlos auf Daten/Funktionen/Methoden
// in einem anderen Thread zugreifen kann. Dies kann man dann via
// einem Glib::Dispatcher realisieren.
Glib::Dispatcher m_dispatcher;
// Speichert den Zeiger auf den Thread ( zum beenden )
Glib::Thread * m_thread;
MyWindow::MyWindow()
: m_end_thread(false), // Der Thread soll laufen
m_vbox(false,10), // Gtk::VBox soll die Elemente nicht homogen anlegen
// und 10 Pixel platz zwischen den einzelnen Elementen lassen
m_button(Glib::locale_to_utf8("Click mich")) // Button text setzen
{
add(m_vbox); // Hier verbinden wir das Gtk::VBox mit dem Fenster
m_vbox.set_border_width(10); // Randbreite des Gtk::VBox auf 10 Pixel setzen
m_vbox.pack_start(m_label); // Verbinden des Gtk::Label mit dem Gtk::VBox
m_vbox.pack_start(m_pbar); // Verbinden des Gtk::ProgressBar mit dem Gtk::VBox
m_vbox.pack_start(m_button); // Verbinden des Gtk::Button mit dem Gtk::VBox
m_pbar.set_pulse_step(0.05f); // Schrittgröße für pulse() setzen / 0.0 - 1.0
// Dem Button die Methode, die er beim clicked Signal ausführen soll, als
// Funktor übergeben
m_button.signal_clicked().connect(sigc::mem_fun(*this,&MyWindow::on_button_click));
// Hier wird die Methode die der Dispatcher beim aufruf ausführen soll
// als Funktor übergeben
m_dispatcher.connect( sigc::mem_fun( m_pbar , &Gtk::ProgressBar::pulse ));
// Hier starten wir den 2. Thread (der erste ist der Hauptthread!) der für
// uns die ProgressBar - Arbeit erledigen wird.
// Hierzu übergeben wir die thread_worker Methode als Funktor.
// das 'true' sagt dem Thread das er joinable sein soll!
// Was auch anhand des Pointers der auf den Thread zeigt und zurückgegeben
// wird überprüft werden.
m_thread = Glib::Thread::create( sigc::mem_fun(*this,&MyWindow::thread_worker),true);
// Nun lassen wir alle Elemente des Fensters anzeigen.
show_all();
}
MyWindow::~MyWindow()
{
// Ein Anonymouer Scope innerhalb einer Funktion/Methode hat den
// Zweck das darin erstellte Objekte beim verlassen zerstört werden
// wir haben hier ein Mutex::Lock objekt erstellt das bei erstellung
// das lock setzt und bei der Zerstörung wieder unlockt
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Wenn der Thread noch läuft
m_end_thread = true; // sagen wir dem Thread das er beenden soll
}
if(m_thread->joinable())
m_thread->join();
}
void MyWindow::on_button_click()
{
static unsigned long count_clicked = 0;
// Hier konvertieren wir den Wert von count_clicked und incrementieren in sogleich
// und übergeben dann den Wert als Glib::ustring an unser Label weiter
// Somit haben wir dann einen Click counter ;)
m_label.set_text(boost::lexical_cast<Glib::ustring>(count_clicked++));
}
m_dispatcher(); // Threadsafer Aufruf der pulse()-Methode
// Dies ist ein anonymer scope [Erklärung siehe Destruktor Defintion]
{
Glib::Mutex::Lock lock(mutex);
if(m_end_thread) // Müssen wir beenden? return;
}// Ende des anonymen scopes, das den effekt hat das das mutex wir unlocked wird
}
}
int main(int argc, char**argv)
{
// Die einzige Änderung hier ist dieser Aufruf:
Glib::thread_init();
// Mit dem Glib::thread_init aufruf wird dafür gesorgt das
// das Gtk+/Glib Subsystem darauf vorbereitet wird das wir
// mehrere Threads benutzen.
void ThreadProgress::progress_increment()
{
// Use an integer because floating point arithmetic is inaccurate --
// we want to finish *exactly* after the 1000th increment.
++progress_;
// Install a one-shot idle handler to launch the threads
// right after the main window has been displayed.
Glib::signal_idle().connect(
SigC::bind_return(SigC::slot(window, &MainWindow::launch_threads), false));
void ThreadProgress::progress_increment()
{
// Use an integer because floating point arithmetic is inaccurate --
// we want to finish *exactly* after the 1000th increment.
++progress_;
// Install a one-shot idle handler to launch the threads
// right after the main window has been displayed.
Glib::signal_idle().connect(
SigC::bind_return(SigC::slot(window, &MainWindow::launch_threads), false));
void ThreadProgress::progress_increment()
{
// Use an integer because floating point arithmetic is inaccurate --
// we want to finish *exactly* after the 1000th increment.
++progress_;
// Install a one-shot idle handler to launch the threads
// right after the main window has been displayed.
Glib::signal_idle().connect(
SigC::bind_return(SigC::slot(window, &MainWindow::launch_threads), false));
Gtk::Main::run(window);
return 0;
}
Zuletzt bearbeitet von evilissimo am 22:34:20 23.06.2005, insgesamt 1-mal bearbeitet
Das Beispiel ist nicht von mir. Es ist von Daniel Elstner und etwas anders als meines.
Ich hab es bewusst ähnlich gemacht, da ich es für ein gutes Beispiel gehalten habe.
In den aktuellen Versionen haben die in den glibmm verzeichnissen aber nur noch non-gtkmm Beispiele, d.h. reine glibmm sources.
Ausserdem hab ich meine Version stark vereinfacht. Und ausreichend kommentiert (hoffe ich) Sollten noch fragen auftreten meldet euch einfach. Und postet nicht irgendwas.
Nächstes Thema anzeigen Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum nicht antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums
für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de
Werbekostenerstattung verdient werden kann.
Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de
enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt
(vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in
privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden.
Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere
übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.