File: chapter-chapter-timeouts.html

package info (click to toggle)
gtkmm-documentation 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 25,772 kB
  • sloc: cpp: 15,541; javascript: 1,208; makefile: 1,080; python: 401; xml: 106; perl: 67; sh: 8
file content (288 lines) | stat: -rw-r--r-- 9,665 bytes parent folder | download
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="highlight.min.css">
<script src="highlight.min.js"></script><script>
      hljs.configure({languages: ['cpp']});
      hljs.highlightAll();
    </script><title>Chapter 24. Timeouts, I/O and Idle Functions</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
<link rel="home" href="index.html" title="Programming with gtkmm 4">
<link rel="up" href="index.html" title="Programming with gtkmm 4">
<link rel="prev" href="sec-keyboardevents-mouse.html" title="Mouse Events">
<link rel="next" href="sec-monitoring-io.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">Chapter 24. Timeouts, I/O and Idle Functions </th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="sec-keyboardevents-mouse.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="sec-monitoring-io.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage"><div><div><h1 class="title">
<a name="chapter-chapter-timeouts"></a>Chapter 24. Timeouts, I/O and Idle Functions </h1></div></div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<ul class="toc">
<li><span class="section"><a href="chapter-chapter-timeouts.html#sec-timeouts">Timeouts</a></span></li>
<li><span class="section"><a href="sec-monitoring-io.html">Monitoring I/O</a></span></li>
<li><span class="section"><a href="sec-idle-functions.html">Idle Functions</a></span></li>
</ul>
</div>


<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="sec-timeouts"></a>Timeouts</h2></div></div></div>


<p>
You may be wondering how to make <span class="application">gtkmm</span> do useful work while it's idling along. Happily,
you have several options. Using the following methods you can create a timeout
method that will be called every few milliseconds.
</p>

<pre class="programlisting"><code class="code">sigc::connection Glib::SignalTimeout::connect(const sigc::slot&lt;bool()&gt;&amp; slot,
                                      unsigned int interval, int priority = Glib::PRIORITY_DEFAULT);
</code></pre>

<p>
The first argument is a <code class="classname">slot</code> 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
<code class="classname">sigc::connection</code> object that can be used to deactivate
the connection using its <code class="methodname">disconnect()</code> method:
</p>

<pre class="programlisting"><code class="code">my_connection.disconnect();
</code></pre>

<p>
Another way of destroying the connection is your signal handler.
It has to be of the type <code class="classname">sigc::slot&lt;bool()&gt;</code>.
As you see from the definition your signal handler has to return a value of
the type <code class="literal">bool</code>. A definition of a sample method might
look like this:
</p>

<pre class="programlisting"><code class="code">bool MyCallback() { std::cout &lt;&lt; "Hello World!\n" &lt;&lt; std::endl; return true; }
</code></pre>

<p>
You can stop the timeout method by returning <code class="literal">false</code> from
your signal handler. Therefore, if you want your
method to be called repeatedly, it should return <code class="literal">true</code>.
</p>

<p>
Here's an example of this technique:
</p>

<p><a class="ulink" href="https://gitlab.gnome.org/GNOME/gtkmm-documentation/tree/master/examples/book/timeout/" target="_top">Source Code</a></p>

<p>File: <code class="filename">timerexample.h</code> (For use with gtkmm 4)</p>
<pre class="programlisting"><code class="code">#ifndef GTKMM_EXAMPLE_TIMEREXAMPLE_H
#define GTKMM_EXAMPLE_TIMEREXAMPLE_H

#include &lt;gtkmm.h&gt;
#include &lt;iostream&gt;
#include &lt;map&gt;

class TimerExample : public Gtk::Window
{
public:
  TimerExample();

protected:
  // signal handlers
  void on_button_add_timer();
  void on_button_delete_timer();
  void on_button_quit();

  // This is the callback function the timeout will call
  bool on_timeout(int timer_number);

  // Member data:

  Gtk::Box 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&lt;int, sigc::connection&gt; 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&lt;int, int&gt; m_counters;
};

#endif // GTKMM_EXAMPLE_TIMEREXAMPLE_H
</code></pre>
<p>File: <code class="filename">main.cc</code> (For use with gtkmm 4)</p>
<pre class="programlisting"><code class="code">#include "timerexample.h"
#include &lt;gtkmm/application.h&gt;

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

  return app-&gt;make_window_and_run&lt;TimerExample&gt;(argc, argv);
}
</code></pre>
<p>File: <code class="filename">timerexample.cc</code> (For use with gtkmm 4)</p>
<pre class="programlisting"><code class="code">#include "timerexample.h"

TimerExample::TimerExample() :
  m_Box(Gtk::Orientation::HORIZONTAL, 10),
  m_ButtonAddTimer("_Add", true),
  m_ButtonDeleteTimer("_Remove", true),
  m_ButtonQuit("_Quit", true),
  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
{
  m_Box.set_margin(10);
  set_child(m_Box);
  m_Box.append(m_ButtonAddTimer);
  m_Box.append(m_ButtonDeleteTimer);
  m_Box.append(m_ButtonQuit);
  m_ButtonAddTimer.set_expand();
  m_ButtonDeleteTimer.set_expand();
  m_ButtonQuit.set_expand();

  // Connect the three buttons:
  m_ButtonQuit.signal_clicked().connect(sigc::mem_fun(*this,
              &amp;TimerExample::on_button_quit));
  m_ButtonAddTimer.signal_clicked().connect(sigc::mem_fun(*this,
              &amp;TimerExample::on_button_add_timer));
  m_ButtonDeleteTimer.signal_clicked().connect(sigc::mem_fun(*this,
              &amp;TimerExample::on_button_delete_timer));
}

void TimerExample::on_button_quit()
{
  set_visible(false);
}

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::slot&lt;bool()&gt; my_slot = sigc::bind(sigc::mem_fun(*this,
              &amp;TimerExample::on_timeout), m_timer_number);

  // This is where we connect the slot to the Glib::signal_timeout()
  auto 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 &lt;&lt; "added timeout " &lt;&lt; m_timer_number++ &lt;&lt; std::endl;
}

void TimerExample::on_button_delete_timer()
{
  // any timers?
  if(m_timers.empty())
  {
    // no timers left
    std::cout &lt;&lt; "Sorry, there are no timers left." &lt;&lt; std::endl;
  }
  else
  {
    // get the number of the first timer
    int timer_number = m_timers.begin()-&gt;first;

    // Give some info to the user:
    std::cout &lt;&lt; "manually disconnecting timer " &lt;&lt; timer_number
        &lt;&lt; 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 &lt;&lt; "This is timer " &lt;&lt; timer_number;

  // decrement and check counter value
  if (--m_counters[timer_number] == 0)
  {
    std::cout &lt;&lt; " being disconnected" &lt;&lt;  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 &lt;&lt; " - " &lt;&lt; m_counters[timer_number] &lt;&lt; "/"
      &lt;&lt; count_value &lt;&lt; std::endl;

 // Keep going (do not disconnect yet):
  return true;
}
</code></pre>


</div>





</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="sec-keyboardevents-mouse.html"><img src="icons/prev.png" alt="Prev"></a> </td>
<td width="20%" align="center"> </td>
<td width="40%" align="right"> <a accesskey="n" href="sec-monitoring-io.html"><img src="icons/next.png" alt="Next"></a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Mouse Events </td>
<td width="20%" align="center"><a accesskey="h" href="index.html"><img src="icons/home.png" alt="Home"></a></td>
<td width="40%" align="right" valign="top"> Monitoring I/O</td>
</tr>
</table>
</div>
</body>
</html>