Idle Functions


Google

What if you have a method you want called when nothing else is happening? Hook it up using the following:

Connection Gtk::Main::idle.connect(Slot0<int> idlefunc, int priority);

This causes gtkmm to call the specified method whenever nothing else is happening. You can add a priority (lower numbers are higher priorities). If you don't supply a priority value, then Gtk::PRIORITY_DEFAULT will be used. There are two ways to remove the signal handler: calling disconnect on the Connection object, or returning false (or 0) in the signal handler, which should be declared as follows:

int idleFunc();

Since this is very similar to the methods above this explanation should be sufficient to understand what's going on. However, here's a little example:

Source location: examples/idle/idle.cc

#include <iostream>
#include <gtkmm/adjustment.h>
#include <gtkmm/button.h>
#include <gtkmm/box.h>
#include <gtkmm/label.h>
#include <gtkmm/progressbar.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <map>


class IdleExample : public Gtk::Window
{
  // the usual stuff - nothing exciting
  Gtk::Button m_quit;
  Gtk::Adjustment  m_percentage_c;
  Gtk::ProgressBar m_progressbar_c;
  Gtk::Adjustment  m_percentage_d;
  Gtk::ProgressBar m_progressbar_d;

public:
  IdleExample();

  // a timer-method
  int timer_callback();
  // a idle-method
  int idle_callback();
};


IdleExample::IdleExample() :
  m_quit("Quit"),
  m_percentage_c(0,0,100,0.5),
  m_progressbar_c(m_percentage_c),
  m_percentage_d(0,0,5000,0.5),
  m_progressbar_d(m_percentage_d)
{
  // connect the signal handlers
  m_quit.pressed.connect(Gtk::Main::quit.slot());

  // put buttons into container
  Gtk::VBox *vbox = manage( new Gtk::VBox(false,5));

  // adding a few widgets
  vbox->pack_start(* manage(new Gtk::Label("Formatting windows drive C:")));
  vbox->pack_start(* manage(new Gtk::Label("100 MB")));
  vbox->pack_start(m_progressbar_c);
  m_progressbar_c.set_show_text(true);

  vbox->pack_start(* manage(new Gtk::Label("")));

  vbox->pack_start(* manage(new Gtk::Label("Formatting windows drive D:")));
  vbox->pack_start(* manage(new Gtk::Label("5000 MB")));
  vbox->pack_start(m_progressbar_d);
  m_progressbar_d.set_show_text(true);

  Gtk::HBox *hbox = manage( new Gtk::HBox(false,10));
  hbox->pack_start(m_quit, true, false);
  vbox->pack_start(*hbox);

  // set border and display all
  set_border_width(5);
  add(*vbox);
  show_all();

  // formattinf drive c in timeout signal handler ;-)
  Gtk::Main::timeout.connect(slot(this,&IdleExample::timer_callback), 50);

  // formatting drive d in idle signal handler ;-)
  Gtk::Main::idle.connect(slot(this,&IdleExample::idle_callback));
}


// increase the progressbar's value and remove signal handler when done
int IdleExample::timer_callback()
{
  float value = m_percentage_c.get_value();
  m_percentage_c.set_value(value + 0.5);
  return value < 99.99;
}


// increase the progressbar's value and remove signal handler when done
// note the diffrence in speed and also the impact of system load
// try to increase system load and watch the drive d value
int IdleExample::idle_callback()
{
  float value = m_percentage_d.get_value();
  m_percentage_d.set_value(value + 0.5);
  return value < 4999.99;
}

int main (int argc, char *argv[])
{
  Gtk::Main app(argc, argv);

  IdleExample example;

  app.run();
  return 0;
}

This example points out the difference of idle and timeout methods a little. If you need methods that are called periodically, and speed is not very important, then you want timeout methods. If you want methods that are called as often as possible (like calculating a fractal in background), then use idle methods.

Try executing the example and increasing the system load. The upper progress bar will increase steadily; the lower one will slow down.