Fonctions de temporisation
Si vous voulez définir une fonction membre appelée quand il n'y aucune autre activité en cours, utilisez :
sigc::connection Glib::SignalIdle::connect( const sigc::slot<bool>& slot, int priority = Glib::PRIORITY_DEFAULT_IDLE);
Cela demande à gtkmm d'appeler la fonction membre indiquée chaque fois qu'il ne se passe rien d'autre. Vous pouvez définir une priorité (les plus petits nombres correspondent aux priorités les plus élevées). Il y a deux manières de déconnecter le gestionnaire de signal : par l'appel de la fonction membre disconnect() sur l'objet sigc::connection ou en renvoyant false dans le gestionnaire du signal, qui doit être déclaré ainsi :
bool idleFunc();
Comme ceci est tout à fait semblable aux fonctions membres des paragraphes précédents, cette explication doit être suffisante pour comprendre comment cela se passe. Toutefois, voici un petit exemple :
File: idleexample.h (For use with gtkmm 3, not gtkmm 2)
#ifndef GTKMM_EXAMPLE_IDLEEXAMPLE_H #define GTKMM_EXAMPLE_IDLEEXAMPLE_H #include <gtkmm.h> #include <iostream> class IdleExample : public Gtk::Window { public: IdleExample(); protected: // Signal Handlers: bool on_timer(); bool on_idle(); void on_button_clicked(); // Member data: Gtk::VBox m_Box; Gtk::Button m_ButtonQuit; Gtk::ProgressBar m_ProgressBar_c; Gtk::ProgressBar m_ProgressBar_d; }; #endif // GTKMM_EXAMPLE_IDLEEXAMPLE_H
File: idleexample.cc (For use with gtkmm 3, not gtkmm 2)
#include "idleexample.h" IdleExample::IdleExample() : m_Box(false, 5), m_ButtonQuit(Gtk::Stock::QUIT) { set_border_width(5); // Put buttons into container // Adding a few widgets: add(m_Box); m_Box.pack_start( *Gtk::manage(new Gtk::Label("Formatting Windows drive C:"))); m_Box.pack_start( *Gtk::manage(new Gtk::Label("100 MB")) ); m_Box.pack_start(m_ProgressBar_c); m_Box.pack_start( *Gtk::manage(new Gtk::Label("")) ); m_Box.pack_start( *Gtk::manage(new Gtk::Label("Formatting Windows drive D:"))); m_Box.pack_start( *Gtk::manage(new Gtk::Label("5000 MB")) ); m_Box.pack_start(m_ProgressBar_d); Gtk::HBox* hbox = Gtk::manage( new Gtk::HBox(false,10)); m_Box.pack_start(*hbox); hbox->pack_start(m_ButtonQuit, Gtk::PACK_EXPAND_PADDING); // Connect the signal handlers: m_ButtonQuit.signal_clicked().connect( sigc::mem_fun(*this, &IdleExample::on_button_clicked) ); // formatting drive c in timeout signal handler - called once every 50ms Glib::signal_timeout().connect( sigc::mem_fun(*this, &IdleExample::on_timer), 50 ); // formatting drive d in idle signal handler - called as quickly as possible Glib::signal_idle().connect( sigc::mem_fun(*this, &IdleExample::on_idle) ); show_all_children(); } void IdleExample::on_button_clicked() { hide(); } // this timer callback function is executed once every 50ms (set in connection // above). Use timeouts when speed is not critical. (ie periodically updating // something). bool IdleExample::on_timer() { double value = m_ProgressBar_c.get_fraction(); // Update progressbar 1/500th each time: m_ProgressBar_c.set_fraction(value + 0.002); return value < 0.99; // return false when done } // This idle callback function is executed as often as possible, hence it is // ideal for processing intensive tasks. bool IdleExample::on_idle() { double value = m_ProgressBar_d.get_fraction(); // Update progressbar 1/5000th each time: m_ProgressBar_d.set_fraction(value + 0.0002); return value < 0.99; // return false when done }
File: main.cc (For use with gtkmm 3, not gtkmm 2)
#include "idleexample.h" #include <gtkmm/main.h> int main (int argc, char *argv[]) { Gtk::Main app(argc, argv); IdleExample example; Gtk::Main::run(example); return 0; }
Cet exemple souligne la différence entre fonctions membres de temporisation et fonctions membres à délai échu. Si vous avez besoin de fonctions appelées périodiquement et que la rapidité n'a pas grosse importance, alors servez-vous des fonctions membres à délai échu. Si vous voulez des fonctions membres appelées aussi souvent que possible (comme des fonctions membres de calcul de fractales en arrière-plan), alors utilisez les fonctions membres de temporisation.
Essayez d'exécuter l'exemple tout en augmentant la charge de votre système. La barre de progression supérieure doit avancer régulièrement ; l'inférieure devrait ralentir.