空闲函数
如果你想要指定一个在无事发生时调用的方法,请使用以下函数:
sigc::connection Glib::SignalIdle::connect(const sigc::slot<bool()>& slot, int priority = Glib::PRIORITY_DEFAULT_IDLE);
这会导致gtkmm在无事发生时调用指定的方法。你可以为其添加优先级(数字越小优先级越高)。删除该信号处理程序的方法有两个:在sigc::connection对象上调用disconnect()、在信号处理程序中返回false,信号处理程序的声明应如下所示:
bool idleFunc();
这与前一小节的方法极其类似,所以在此不再进行过多的解释。以下是个小例子:
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 }
这个例子指出了空闲与超时方法的微小区别。如果你需要定期调用,并且速度并不重要则你应该使用超时方法。如果你需要尽可能多的调用方法(例如在后台计算分形)那你应该使用空闲方法。
尝试执行此示例并逐渐增加系统的负载。上方的进度条将稳定的逐渐增加;下方的则会增加的越来越慢。