1
2
3
4
5 """ Gtk2 based reactor.
6
7 BRisa can be easily embedded in applications with Gtk GUI's. For achieving that,
8 the FIRST THING you should do in your application is to install this reactor.
9
10 >>> from brisa.core.reactors import Gtk2Reactor
11 >>> reactor = Gtk2Reactor()
12
13 On the first time you call Gtk2Reactor() the reactor will be installed and
14 BRisa modules will adapt themselves to work with this reactor. Subsequent
15 calls to it will only retrieve the already installed reactor - so, any internal
16 module of your application can retrieve the reactor when you need to add timers
17 or file descriptors.
18
19 When starting up your application, instead of calling gtk.main(), you should
20 call reactor.main() (which is internally the same thing but you should use the
21 name "reactor" for avoiding confusions).
22
23 Calling reactor.main_quit() is also recommended instead of gtk.main_quit().
24 """
25
26 from brisa.core.ireactor import ReactorInterface, EVENT_TYPE_READ, \
27 EVENT_TYPE_WRITE, EVENT_TYPE_EXCEPTION
28
29 from brisa.core import log
30
31
32 try:
33 import gobject
34 import gtk
35 gtk.gdk.threads_init()
36 __all__ = ('Gtk2Reactor', )
37 except ImportError:
38 __all__ = ()
39
40 log = log.getLogger('reactor.gtk2')
41
42
44
45 _stop_funcs = []
46 _start_funcs = []
47
48 - def add_timer(self, interval, callback, threshold=0):
49 """ Add timer.
50
51 @note: should return an ID assigned to the timer, so that it can be
52 removed by rem_timer().
53 """
54 return gobject.timeout_add(int(interval*(10**3)), callback)
55
57 """ Removes a timer.
58 """
59 return gobject.source_remove(timer_id)
60
61 - def add_fd(self, fd, event_callback, event_type):
62 """ Adds a fd for watch.
63 """
64 condition = None
65 if event_type & EVENT_TYPE_READ:
66 condition = gobject.IO_IN | gobject.IO_PRI
67 if event_type & EVENT_TYPE_WRITE:
68 if not condition:
69 condition = gobject.IO_OUT
70 else:
71 condition = condition | gobject.IO_OUT
72 if event_type & EVENT_TYPE_EXCEPTION:
73 if not condition:
74 condition = gobject.IO_ERR
75 else:
76 condition = condition | gobject.IO_ERR
77
78 ret = gobject.io_add_watch(fd, condition, event_callback)
79 return ret
80
82 """ Removes a fd from being watched.
83 """
84 return gobject.source_remove(fd_handler)
85
87 """ Registers a function to be called before entering the STOPPED
88 state.
89
90 @param func: function
91 @type func: callable
92 """
93 if func not in self._stop_funcs:
94 self._stop_funcs.append(func)
95
97 """ Removes a registered function.
98
99 @param func: function
100 @type func: callable
101 """
102 if func in self._stop_funcs:
103 self._stop_funcs.remove(func)
104
106 """ Registers a function to be called before starting the main loop.
107
108 @param func: function
109 @type func: callable
110 """
111 if func not in self._start_funcs:
112 self._start_funcs.append(func)
113
115 """ Removes a registered function.
116
117 @param func: function
118 @type func: callable
119 """
120 if func in self._start_funcs:
121 self._start_funcs.remove(func)
122
124 """ Runs a single iteration of the main loop. Reactor enters the
125 RUNNING state while this method executes.
126 """
127 gtk.main_iteration()
128
130 """ Enters the RUNNING state by running the main loop until
131 main_quit() is called.
132 """
133 self._main_call_before_start_funcs()
134 gtk.main()
135 self._main_call_after_stop_funcs()
136
137 - def main_quit(self):
138 """ Terminates the main loop.
139 """
140 gtk.main_quit()
141
143 """ Returns True if the main loop is running
144 """
145 return True if gtk.main_level() else False
146
148 """ Calls registered functions to be called after the main loop is
149 stopped.
150 """
151 for cb in self._stop_funcs:
152 cb()
153
155 """ Call registered functions to be called before starting the main
156 loop.
157 """
158 for cb in self._start_funcs:
159 cb()
160