1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter17.Timeouts, I/O and Idle Functions </title><meta name="generator" content="DocBook XSL Stylesheets V1.64.1"><link rel="home" href="index.html" title="Programming with gtkmm2"><link rel="up" href="index.html" title="Programming with gtkmm2"><link rel="previous" href="ch16s04.html" title="Examples"><link rel="next" href="ch17s02.html" title="Monitoring I/O"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter17.Timeouts, I/O and Idle Functions </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch16s04.html">Prev</a></td><th width="60%" align="center"></th><td width="20%" align="right"><a accesskey="n" href="ch17s02.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="sec-timeouts"></a>Chapter17.Timeouts, I/O and Idle Functions </h2></div></div><div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="ch17.html#id2518043">Timeouts</a></span></dt><dt><span class="sect1"><a href="ch17s02.html">Monitoring I/O</a></span></dt><dt><span class="sect1"><a href="ch17s03.html">Idle Functions</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2518043"></a>Timeouts</h2></div></div><div></div></div><p>
You may be wondering how to make gtkmm do useful work while it's
idling along (well, sleeping actually) in <tt class="literal">Gtk::Main::run()</tt>. Happily,
you have several options. Using the following methods you can create
a timeout method that will be called every few milliseconds.
</p><p>
</p><pre class="programlisting">
SigC::Connection Glib::SignalTimeout::connect(const SigC::Slot0<bool>& slot, unsigned int interval, int priority = Glib::PRIORITY_DEFAULT);
</pre><p>
</p><p>
The first argument is a slot you wish to have called when the timeout
occurs. The second argument is the number of milliseconds between
calls to that method. You receive a <tt class="literal">SigC::Connection</tt> object that can be
used to deactivate the connection.
</p><p>
</p><pre class="programlisting">
MyConnection.disconnect();
</pre><p>
</p><p>
to destroy the connection. Another way of destroying the Connection
is your signal handler. It has to be of the type
<tt class="literal">SigC::Slot0<bool></tt>. As you see from the definition your
signal handler has to return a value of the type <tt class="literal">bool</tt>. A
definition of a sample method might look like this:
</p><p>
</p><pre class="programlisting">
bool MyCallback() { std::cout << "Hello World!\n"; return true; }
</pre><p>
</p><p>
You can stop the timeout method by returning <tt class="literal">false</tt> from
your signal handler. Therefore, if you want your
method to be called repeatedly, it should return <tt class="literal">true</tt>.
</p><p>
Here's an example of this technique:
</p><p><a href="../../../examples/book/timeout/" target="_top">Source Code</a></p><p>File: timerexample.h
</p><pre class="programlisting">
#ifndef GTKMM_EXAMPLE_TIMEREXAMPLE_H
#define GTKMM_EXAMPLE_TIMEREXAMPLE_H
#include <gtkmm.h>
#include <iostream>
#include <map>
class TimerExample : public Gtk::Window
{
public:
TimerExample();
protected:
// signal handlers
void on_button_add_timer();
void on_button_delete_timer();
// This is the callback function the timeout will call
bool on_timeout(int timer_number);
// Member data:
Gtk::HBox m_Box;
Gtk::Button m_ButtonAddTimer, m_ButtonDeleteTimer, m_ButtonQuit;
// Keep track of the timers being added:
int m_timer_number;
// These two constants are initialized in the constructor's member initializer:
const int count_value;
const int timeout_value;
// STL map for storing our connections
std::map<int, SigC::Connection> m_timers;
// STL map for storing our timer values.
// Each timer counts back from COUNT_VALUE to 0 and is removed when it reaches 0
std::map<int, int> m_counters;
};
#endif // GTKMM_EXAMPLE_TIMEREXAMPLE_H
</pre><p>
</p><p>File: main.cc
</p><pre class="programlisting">
#include "timerexample.h"
#include <gtkmm/main.h>
int main (int argc, char *argv[])
{
Gtk::Main app(argc, argv);
TimerExample example;
Gtk::Main::run(example);
return 0;
}
</pre><p>
</p><p>File: timerexample.cc
</p><pre class="programlisting">
#include "timerexample.h"
TimerExample::TimerExample() :
m_Box(true, 10),
m_ButtonAddTimer(Gtk::Stock::ADD), // use Gtk::Stock wherever possible for buttons, etc.
m_ButtonDeleteTimer(Gtk::Stock::REMOVE),
m_ButtonQuit(Gtk::Stock::QUIT),
m_timer_number(0), // start numbering the timers at 0
count_value(5), // each timer will count down 5 times before disconnecting
timeout_value(1500) // 1500 ms = 1.5 seconds
{
set_border_width(10);
add(m_Box);
m_Box.pack_start(m_ButtonAddTimer);
m_Box.pack_start(m_ButtonDeleteTimer);
m_Box.pack_start(m_ButtonQuit);
// Connect the three buttons:
m_ButtonQuit.signal_clicked().connect(SigC::slot(*this, &Gtk::Widget::hide));
m_ButtonAddTimer.signal_clicked().connect(SigC::slot(*this,&TimerExample::on_button_add_timer));
m_ButtonDeleteTimer.signal_clicked().connect(SigC::slot(*this,&TimerExample::on_button_delete_timer));
show_all_children();
}
void TimerExample::on_button_add_timer()
{
// Creation of a new object prevents long lines and shows us a little
// how slots work. We have 0 parameters and bool as a return value
// after calling SigC::bind.
SigC::Slot0<bool> my_slot = SigC::bind(SigC::slot(*this, &TimerExample::on_timeout), m_timer_number);
// This is where we connect the slot to the Glib::signal_timeout()
SigC::Connection conn = Glib::signal_timeout().connect(my_slot, timeout_value);
// Remember the connection:
m_timers[m_timer_number] = conn;
// Initialize timer count:
m_counters[m_timer_number] = count_value + 1;
// Print some info to the console for the user:
std::cout << "added timeout " << m_timer_number++ << std::endl;
}
void TimerExample::on_button_delete_timer()
{
// any timers?
if(m_timers.empty())
{
// no timers left
std::cout << "Sorry, there are no timers left." << std::endl;
}
else
{
// get the number of the first timer
int timer_number = m_timers.begin()->first;
// Give some info to the user:
std::cout << "manually disconnecting timer " << timer_number << std::endl;
// Remove the entry in the counter values
m_counters.erase(timer_number);
// Diconnect the signal handler:
m_timers[timer_number].disconnect();
// Forget the connection:
m_timers.erase(timer_number);
}
}
bool TimerExample::on_timeout(int timer_number)
{
// Print the timer:
std::cout << "This is timer " << timer_number;
// decrement and check counter value
if (--m_counters[timer_number] == 0)
{
std::cout << " being disconnected" << std::endl;
// delete the counter entry in the STL MAP
m_counters.erase(timer_number);
// delete the connection entry in the STL MAP
m_timers.erase(timer_number);
// Note that we do not have to explicitly call disconnect() on the connection
// since Gtk::Main does this for us when we return false.
return false;
}
// Print the timer value
std::cout << " - " << m_counters[timer_number] << "/" << count_value << std::endl;
// Keep going (do not disconnect yet):
return true;
}
</pre><p>
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch16s04.html">Prev</a></td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"><a accesskey="n" href="ch17s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Examples</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">Monitoring I/O</td></tr></table></div></body></html>
|