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 :

Source Code

File: idleexample.h (For use with gtkmm 4)

#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::Box m_Box;
  Gtk::Button m_ButtonQuit;
  Gtk::ProgressBar m_ProgressBar_c;
  Gtk::ProgressBar m_ProgressBar_d;
};

#endif // GTKMM_EXAMPLE_IDLEEXAMPLE_H

File: main.cc (For use with gtkmm 4)

#include "idleexample.h"
#include <gtkmm/application.h>

int main (int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  return app->make_window_and_run<IdleExample>(argc, argv);
}

File: idleexample.cc (For use with gtkmm 4)

#include "idleexample.h"

IdleExample::IdleExample() :
  m_Box(Gtk::Orientation::VERTICAL, 5),
  m_ButtonQuit("_Quit", true)
{
  m_Box.set_margin(5);

  // Put buttons into container

  // Adding a few widgets:
  set_child(m_Box);
  m_Box.append(*Gtk::make_managed<Gtk::Label>("Formatting Windows drive C:"));
  m_Box.append(*Gtk::make_managed<Gtk::Label>("100 MB"));
  m_Box.append(m_ProgressBar_c);
  m_ProgressBar_c.set_expand();

  m_Box.append(*Gtk::make_managed<Gtk::Label>(""));

  m_Box.append(*Gtk::make_managed<Gtk::Label>("Formatting Windows drive D:"));
  m_Box.append(*Gtk::make_managed<Gtk::Label>("5000 MB"));
  m_Box.append(m_ProgressBar_d);
  m_ProgressBar_d.set_expand();

  auto hbox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL,10);
  m_Box.append(*hbox);
  hbox->append(m_ButtonQuit);
  m_ButtonQuit.set_expand();
  m_ButtonQuit.set_halign(Gtk::Align::END);
  m_ButtonQuit.set_valign(Gtk::Align::END);

  // 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) );
}


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
}

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.