1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
3
<title>Twisted Documentation: Choosing a Reactor and GUI Toolkit Integration</title>
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
8
<h1 class="title">Choosing a Reactor and GUI Toolkit Integration</h1>
9
<div class="toc"><ol><li><a href="#auto0">Overview</a></li><li><a href="#auto1">Reactor Functionality</a></li><li><a href="#auto2">General Purpose Reactors</a></li><ul><li><a href="#auto3">Select()-based Reactor</a></li><li><a href="#auto4">Poll()-based Reactor</a></li></ul><li><a href="#auto5">Platform-Specific Reactors</a></li><ul><li><a href="#auto6">KQueue</a></li><li><a href="#auto7">Win32 (WFMO)</a></li><li><a href="#auto8">Win32 (IOCP)</a></li><li><a href="#auto9">Epoll-based Reactor</a></li></ul><li><a href="#auto10">GUI Integration Reactors</a></li><ul><li><a href="#auto11">GTK+</a></li><li><a href="#auto12">CoreFoundation</a></li></ul><li><a href="#auto13">Non-Reactor GUI Integration</a></li><ul><li><a href="#auto14">Tkinter</a></li><li><a href="#auto15">wxPython</a></li><li><a href="#auto16">PyUI</a></li></ul></ol></div>
13
<h2>Overview<a name="auto0"/></h2>
15
<p>Twisted provides a variety of implementations of the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.reactor.html" title="twisted.internet.reactor">twisted.internet.reactor</a></code>. The specialized
16
implementations are suited for different purposes and are
17
designed to integrate better with particular platforms.</p>
19
<p>The general purpose reactor implementations are:</p>
22
<li><a href="#select" shape="rect">The select()-based reactor</a></li>
23
<li><a href="#poll" shape="rect">The poll()-based reactor</a></li>
26
<p>Platform-specific reactor implementations exist for:</p>
29
<li><a href="#kqueue" shape="rect">KQueue for FreeBSD and OS X</a></li>
30
<li><a href="#win32_wfmo" shape="rect">Win32 (WFMO)</a></li>
31
<li><a href="#win32_iocp" shape="rect">Win32 (IOCP)</a></li>
32
<li><a href="#cfreactor" shape="rect">Mac OS X</a></li>
33
<li><a href="#epoll" shape="rect">Epoll for Linux 2.6</a></li>
36
<p>The remaining custom reactor implementations provide support
37
for integrating with the native event loops of various graphical
38
toolkits. This lets your Twisted application use all of the
39
usual Twisted APIs while still being a graphical application.</p>
41
<p>Twisted currently integrates with the following graphical
45
<li><a href="#gtk" shape="rect">GTK+ 1.2 and 2.0</a></li>
46
<li><a href="#tkinter" shape="rect">Tkinter</a></li>
47
<li><a href="#wxpython" shape="rect">WxPython</a></li>
48
<li><a href="#win32_wfmo" shape="rect">Win32</a></li>
49
<li><a href="#cfreactor" shape="rect">CoreFoundation</a></li>
50
<li><a href="#pyui" shape="rect">PyUI</a></li>
53
<p>When using applications that runnable using <code>twistd</code>, e.g.
54
TAPs or plugins, there is no need to choose a reactor explicitly, since
55
this can be chosen using <code>twistd</code>'s -r option.</p>
57
<p>In all cases, the event loop is started by calling <code class="python">reactor.run()</code>. In all cases, the event loop
58
should be stopped with <code class="python">reactor.stop()</code>.</p>
60
<p><strong>IMPORTANT:</strong> installing a reactor should be the first thing
61
done in the app, since any code that does
62
<code class="python">from twisted.internet import reactor</code> will automatically
63
install the default reactor if the code hasn't already installed one.</p>
65
<h2>Reactor Functionality<a name="auto1"/></h2>
67
<table border="1" cellpadding="7" cellspacing="0" title="Summary of reactor features">
68
<tr><td colspan="1" rowspan="1"/><th colspan="1" rowspan="1">Status</th><th colspan="1" rowspan="1">TCP</th><th colspan="1" rowspan="1">SSL</th><th colspan="1" rowspan="1">UDP</th><th colspan="1" rowspan="1">Threading</th><th colspan="1" rowspan="1">Processes</th><th colspan="1" rowspan="1">Scheduling</th><th colspan="1" rowspan="1">Platforms</th></tr>
69
<tr><th colspan="1" rowspan="1">select()</th><td colspan="1" rowspan="1">Stable</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Unix, Win32</td></tr>
70
<tr><th colspan="1" rowspan="1">poll()</th><td colspan="1" rowspan="1">Stable</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Unix</td></tr>
71
<tr><th colspan="1" rowspan="1">Win32 (WFMO)</th><td colspan="1" rowspan="1">Experimental</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Win32</td></tr>
72
<tr><th colspan="1" rowspan="1">Win32 (IOCP)</th><td colspan="1" rowspan="1">Experimental</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">N</td><td colspan="1" rowspan="1">N</td><td colspan="1" rowspan="1">N</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Win32</td></tr>
73
<tr><th colspan="1" rowspan="1">CoreFoundation</th><td colspan="1" rowspan="1">Unmaintained</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">OS X</td></tr>
74
<tr><th colspan="1" rowspan="1">epoll</th><td colspan="1" rowspan="1">Stable</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Linux 2.6</td></tr>
75
<tr><th colspan="1" rowspan="1">Gtk</th><td colspan="1" rowspan="1">Stable</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Unix, Win32</td></tr>
76
<tr><th colspan="1" rowspan="1">wx</th><td colspan="1" rowspan="1">Experimental</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Unix, Win32</td></tr>
77
<tr><th colspan="1" rowspan="1">kqueue</th><td colspan="1" rowspan="1">Experimental</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">Y</td><td colspan="1" rowspan="1">FreeBSD</td></tr>
80
<h2>General Purpose Reactors<a name="auto2"/></h2>
82
<h3>Select()-based Reactor<a name="auto3"/></h3><a name="select" shape="rect"/>
84
<p>The <code>select</code> reactor is currently the default reactor on all
85
platforms. The following code will install it, if no other reactor has
88
<pre class="python"><p class="py-linenumber">1
89
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
92
<p>In the future, if another reactor becomes the default, but the
93
<code>select</code> reactor is desired, it may be installed via:</p>
95
<pre class="python"><p class="py-linenumber">1
99
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">selectreactor</span>
100
<span class="py-src-variable">selectreactor</span>.<span class="py-src-variable">install</span>()
102
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
105
<h3>Poll()-based Reactor<a name="auto4"/></h3><a name="poll" shape="rect"/>
107
<p>The PollReactor will work on any platform that provides <code class="python">poll()</code> (while OS X provides <code class="python">poll()</code>, it is not recommended to use the
108
PollReactor on OS X due to bugs in its implementation of the call).
109
With larger numbers of connected sockets, it may provide for better
110
performance than the SelectReactor.</p>
112
<pre class="python"><p class="py-linenumber">1
116
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">pollreactor</span>
117
<span class="py-src-variable">pollreactor</span>.<span class="py-src-variable">install</span>()
119
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
122
<h2>Platform-Specific Reactors<a name="auto5"/></h2>
124
<h3>KQueue<a name="auto6"/></h3><a name="kqueue" shape="rect"/>
126
<p>The KQueue Reactor allows Twisted to use FreeBSD's kqueue mechanism for
127
event scheduling. See instructions in the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.kqreactor.html" title="twisted.internet.kqreactor">twisted.internet.kqreactor</a></code>'s
128
docstring for installation notes.</p>
130
<pre class="python"><p class="py-linenumber">1
134
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">kqreactor</span>
135
<span class="py-src-variable">kqreactor</span>.<span class="py-src-variable">install</span>()
137
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
141
<h3>Win32 (WFMO)<a name="auto7"/></h3><a name="win32_wfmo" shape="rect"/>
143
<p>The Win32 reactor is not yet complete and has various limitations
144
and issues that need to be addressed. The reactor supports GUI integration
145
with the win32gui module, so it can be used for native Win32 GUI applications.
148
<pre class="python"><p class="py-linenumber">1
152
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">win32eventreactor</span>
153
<span class="py-src-variable">win32eventreactor</span>.<span class="py-src-variable">install</span>()
155
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
158
<h3>Win32 (IOCP)<a name="auto8"/></h3><a name="win32_iocp" shape="rect"/>
161
Windows provides a fast, scalable event notification system known as IO
162
Completion Ports, or IOCP for short. Twisted includes a reactor based
163
on IOCP which is nearly complete. The reactor has a handful of known
164
bugs and lacks SSL support.
167
<pre class="python"><p class="py-linenumber">1
171
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">iocpreactor</span>
172
<span class="py-src-variable">iocpreactor</span>.<span class="py-src-variable">install</span>()
174
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
177
<h3>Epoll-based Reactor<a name="auto9"/></h3><a name="epoll" shape="rect"/>
179
<p>The EPollReactor will work on any platform that provides
180
<code class="python">epoll</code>, today only Linux 2.6 and over. The
181
implementation of the epoll reactor currently uses the Level Triggered
182
interface, which is basically like poll() but scales much better.</p>
184
<pre class="python"><p class="py-linenumber">1
188
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">epollreactor</span>
189
<span class="py-src-variable">epollreactor</span>.<span class="py-src-variable">install</span>()
191
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
194
<h2>GUI Integration Reactors<a name="auto10"/></h2>
196
<h3>GTK+<a name="auto11"/></h3><a name="gtk" shape="rect"/>
198
<p>Twisted integrates with <a href="http://www.pygtk.org/" shape="rect">PyGTK</a>, versions 1.2 (<code>gtkreactor</code>) and 2.0
199
(<code>gtk2reactor</code>). Sample applications using GTK+ and
200
Twisted are available in the Twisted SVN.</p>
202
<p>GTK-2.0 split the event loop out of the GUI toolkit, into a separate
203
module called <q>glib</q>. To run an application using the glib event
204
loop, use the <code>glib2reactor</code>. This will be slightly faster
205
than <code>gtk2reactor</code> (and does not require a working X display),
206
but cannot be used to run GUI applications.</p>
208
<pre class="python"><p class="py-linenumber">1
212
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">gtkreactor</span> <span class="py-src-comment"># for gtk-1.2</span>
213
<span class="py-src-variable">gtkreactor</span>.<span class="py-src-variable">install</span>()
215
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
218
<pre class="python"><p class="py-linenumber">1
222
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">gtk2reactor</span> <span class="py-src-comment"># for gtk-2.0</span>
223
<span class="py-src-variable">gtk2reactor</span>.<span class="py-src-variable">install</span>()
225
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
228
<pre class="python"><p class="py-linenumber">1
232
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">glib2reactor</span> <span class="py-src-comment"># for non-GUI apps</span>
233
<span class="py-src-variable">glib2reactor</span>.<span class="py-src-variable">install</span>()
235
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
238
<h3>CoreFoundation<a name="auto12"/></h3><a name="cfreactor" shape="rect"/>
240
<p>Twisted integrates with <a href="http://pyobjc.sf.net/" shape="rect">PyObjC</a>, version 1.0. Sample applications using Cocoa and Twisted
241
are available in the examples directory under
242
<code>threadedselect/Cocoa</code>.</p>
244
<pre class="python"><p class="py-linenumber">1
248
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">cfreactor</span>
249
<span class="py-src-variable">cfreactor</span>.<span class="py-src-variable">install</span>()
251
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
254
<h2>Non-Reactor GUI Integration<a name="auto13"/></h2>
256
<h3>Tkinter<a name="auto14"/></h3><a name="tkinter" shape="rect"/>
258
<p>The support for <a href="http://www.python.org/topics/tkinter/" shape="rect">Tkinter</a> doesn't use a specialized reactor. Instead, there is
259
some specialized support code:</p>
261
<pre class="python"><p class="py-linenumber"> 1
272
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">Tkinter</span> <span class="py-src-keyword">import</span> *
273
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">tksupport</span>
275
<span class="py-src-variable">root</span> = <span class="py-src-variable">Tk</span>()
277
<span class="py-src-comment"># Install the Reactor support</span>
278
<span class="py-src-variable">tksupport</span>.<span class="py-src-variable">install</span>(<span class="py-src-variable">root</span>)
280
<span class="py-src-comment"># at this point build Tk app as usual using the root object,</span>
281
<span class="py-src-comment"># and start the program with "reactor.run()", and stop it</span>
282
<span class="py-src-comment"># with "reactor.stop()".</span>
285
<h3>wxPython<a name="auto15"/></h3><a name="wxpython" shape="rect"/>
287
<p>Twisted currently supports two methods of integrating
288
wxPython. Unfortunately, neither method will work on all wxPython
289
platforms (such as GTK2 or Windows). It seems that the only
290
portable way to integrate with wxPython is to run it in a separate
291
thread. One of these methods may be sufficient if your wx app is
292
limited to a single platform.</p>
294
<p>As with <a href="#tkinter" shape="rect">Tkinter</a>, the support for integrating
295
Twisted with a <a href="http://www.wxpython.org" shape="rect">wxPython</a>
296
application uses specialized support code rather than a simple reactor.</p>
298
<pre class="python"><p class="py-linenumber">1
303
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">wxPython</span>.<span class="py-src-variable">wx</span> <span class="py-src-keyword">import</span> *
304
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">wxsupport</span>, <span class="py-src-variable">reactor</span>
306
<span class="py-src-variable">myWxAppInstance</span> = <span class="py-src-variable">wxApp</span>(<span class="py-src-number">0</span>)
307
<span class="py-src-variable">wxsupport</span>.<span class="py-src-variable">install</span>(<span class="py-src-variable">myWxAppInstance</span>)
310
<p>However, this has issues when running on Windows, so Twisted now
311
comes with alternative wxPython support using a reactor. Using
312
this method is probably better. Initialization is done in two
313
stages. In the first, the reactor is installed:</p>
315
<pre class="python"><p class="py-linenumber">1
317
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">wxreactor</span>
318
<span class="py-src-variable">wxreactor</span>.<span class="py-src-variable">install</span>()
321
<p>Later, once a <code class="python">wxApp</code> instance has
322
been created, but before <code class="python">reactor.run()</code>
325
<pre class="python"><p class="py-linenumber">1
327
</p><span class="py-src-variable">myWxAppInstance</span> = <span class="py-src-variable">wxApp</span>(<span class="py-src-number">0</span>)
328
<span class="py-src-variable">reactor</span>.<span class="py-src-variable">registerWxApp</span>(<span class="py-src-variable">myWxAppInstance</span>)
331
<p>An example Twisted application that uses WxWindows can be found
332
in <code class="py-filename">doc/examples/wxdemo.py</code>.</p>
334
<h3>PyUI<a name="auto16"/></h3><a name="pyui" shape="rect"/>
336
<p>As with <a href="#tkinter" shape="rect">Tkinter</a>, the support for integrating
337
Twisted with a <a href="http://pyui.sourceforge.net" shape="rect">PyUI</a>
338
application uses specialized support code rather than a simple reactor.</p>
340
<pre class="python"><p class="py-linenumber">1
343
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">pyuisupport</span>, <span class="py-src-variable">reactor</span>
345
<span class="py-src-variable">pyuisupport</span>.<span class="py-src-variable">install</span>(<span class="py-src-variable">args</span>=(<span class="py-src-number">640</span>, <span class="py-src-number">480</span>), <span class="py-src-variable">kw</span>={<span class="py-src-string">'renderer'</span>: <span class="py-src-string">'gl'</span>})
348
<p>An example Twisted application that uses PyUI can be found in <code class="py-filename">doc/examples/pyuidemo.py</code>.</p>
352
<p><a href="index.html">Index</a></p>
353
<span class="version">Version: 10.0.0</span>
b'\\ No newline at end of file'