Funciones en espera

Si quiere especificar un método que se llame cuando no está sucediendo nada más, use lo siguiente:

sigc::connection  Glib::SignalIdle::connect(const sigc::slot<bool()>& slot,
                                    int priority = Glib::PRIORITY_DEFAULT_IDLE);

Esto hace que gtkmm llame al método especificado siempre que no esté sucediendo nada más. Puede añadir una prioridad (los números más bajos indican prioridades más altas). Hay dos maneras de eliminar el gestor de señales: llamando a disconnect() en el objeto sigc::connection, o devolviendo false en el gestor de señales, que debe declararse como se indica a continuación:

bool idleFunc();

Dado que esto es muy similar a los métodos mencionados anteriormente esta explicación es suficiente para entender lo que sucede. Sin embargo, aquí hay un pequeño ejemplo:

Código fuente

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
}

Este ejemplo señala un poco la diferencia entre los métodos en espera y los de tiempo de espera. Si necesita métodos que se llamen periódicamente, y la velocidad no es muy importante, entonces quiere métodos de tiempo de espera. Si quiere métodos que se llamen tan a menudo como sea posible (como calcular un fractal en segundo plano), entonces use métodos de espera.

Pruebe a ejecutar este ejemplo e incrementar la carga del sistema. La barra de progreso superior incrementará progresivamente, la inferior irá más lentamente.