4 from oscopy
.readers
.detect_reader
import DetectReader
5 from oscopy
import Figure
8 from matplotlib
.backends
.backend_gtkagg
import FigureCanvasGTKAgg
as FigureCanvas
9 from matplotlib
.backends
.backend_gtkagg
import NavigationToolbar2GTKAgg
as NavigationToolbar
11 def report_error(parent
, msg
):
12 dlg
= gtk
.MessageDialog(parent
,
13 gtk
.DIALOG_MODAL | gtk
.DIALOG_DESTROY_WITH_PARENT
,
14 gtk
.MESSAGE_ERROR
, gtk
.BUTTONS_OK
, msg
)
15 dlg
.set_title(parent
.get_title())
21 <menubar name="MenuBar">
23 <menuitem action="Add file"/>
24 <menuitem action="Quit"/>
30 self
._scale
_to
_str
= {'lin': 'Linear', 'logx': 'LogX', 'logy': 'LogY',\
32 self
._layout
_to
_str
= {'horiz': 'Horizontal', 'vert':'Vertical',\
34 self
._ctxt
= oscopy
.Context()
35 self
._store
= gtk
.TreeStore(gobject
.TYPE_STRING
, gobject
.TYPE_PYOBJECT
)
36 self
._create
_widgets
()
37 #self._add_file('demo/irf540.dat')
38 #self._add_file('demo/ac.dat')
39 #self._add_file('demo/res.dat')
41 self
._windows
_to
_figures
= {}
42 self
._current
_graph
= None
43 self
._current
_figure
= None
45 def _add_file(self
, filename
):
47 self
._ctxt
.read(filename
)
48 except NotImplementedError:
49 report_error(self
._mainwindow
,
50 'Could not find a reader for %s' % filename
)
52 it
= self
._store
.append(None, (filename
, None))
53 for name
, sig
in self
._ctxt
.readers
[filename
].signals
.iteritems():
54 self
._store
.append(it
, (name
, sig
))
56 def _action_add_file(self
, action
):
57 dlg
= gtk
.FileChooserDialog('Add file', parent
=self
._mainwindow
,
58 buttons
=(gtk
.STOCK_CANCEL
, gtk
.RESPONSE_REJECT
,
59 gtk
.STOCK_OK
, gtk
.RESPONSE_ACCEPT
))
61 filename
= dlg
.get_filename()
63 if resp
== gtk
.RESPONSE_ACCEPT
:
64 self
._add
_file
(filename
)
66 def _action_quit(self
, action
):
69 def _create_menubar(self
):
71 # (name, stock-id, label, accelerator, tooltip, callback)
73 ('File', None, '_File'),
74 ('Add file', gtk
.STOCK_ADD
, '_Add file', None, None,
75 self
._action
_add
_file
),
76 ('Quit', gtk
.STOCK_QUIT
, '_Quit', None, None,
79 actiongroup
= gtk
.ActionGroup('App')
80 actiongroup
.add_actions(actions
)
82 uimanager
= gtk
.UIManager()
83 uimanager
.add_ui_from_string(self
.__ui
)
84 uimanager
.insert_action_group(actiongroup
, 0)
85 return uimanager
.get_accel_group(), uimanager
.get_widget('/MenuBar')
87 def _create_treeview(self
):
88 col
= gtk
.TreeViewColumn('Signal', gtk
.CellRendererText(), text
=0)
91 tv
.set_model(self
._store
)
92 tv
.connect('row-activated', self
._row
_activated
)
95 def _create_widgets(self
):
96 accel_group
, self
._menubar
= self
._create
_menubar
()
97 self
._treeview
= self
._create
_treeview
()
99 sw
= gtk
.ScrolledWindow()
100 sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_AUTOMATIC
)
101 sw
.add(self
._treeview
)
104 vbox
.pack_start(self
._menubar
, False)
107 w
= self
._mainwindow
= gtk
.Window(gtk
.WINDOW_TOPLEVEL
)
108 w
.set_title('Oscopy GUI')
110 w
.add_accel_group(accel_group
)
111 w
.connect('destroy', lambda *x
: self
._action
_quit
(None))
112 w
.set_default_size(400, 300)
115 def _signals_menu_item_activated(self
, menuitem
, user_data
):
116 fig
, parent_it
, it
= user_data
117 name
, sig
= self
._store
.get(it
, 0, 1)
118 print 'Adding signal %s to %s' % (name
, fig
)
122 if self
._current
_graph
is not None:
123 self
._current
_graph
.insert({name
: sig
})
124 if fig
.canvas
is not None:
127 def _graph_menu_item_activated(self
, menuitem
, user_data
):
132 def _scale_menu_item_activated(self
, menuitem
, user_data
):
133 fig
, scale
= user_data
134 self
._current
_graph
.set_scale(scale
)
135 if fig
.canvas
is not None:
138 def _layout_menu_item_activated(self
, menuitem
, user_data
):
139 fig
, layout
= user_data
141 if fig
.canvas
is not None:
144 def _create_scale_menu(self
, fig
):
146 for scale
in self
._scale
_to
_str
.keys():
147 item
= gtk
.CheckMenuItem(self
._scale
_to
_str
[scale
])
148 item
.set_active(self
._current
_graph
.scale
== scale
)
149 item
.connect('activate', self
._scale
_menu
_item
_activated
,
154 def _create_layout_menu(self
, fig
):
156 for layout
in self
._layout
_to
_str
.keys():
157 item
= gtk
.CheckMenuItem(self
._layout
_to
_str
[layout
])
158 item
.set_active(fig
.layout
== layout
)
159 item
.connect('activate', self
._layout
_menu
_item
_activated
,
164 def _create_graph_menu(self
, fig
):
166 item_add
= gtk
.MenuItem('Add graph')
167 item_add
.connect('activate', self
._graph
_menu
_item
_activated
,
169 menu
.append(item_add
)
172 def _create_signals_menu(self
, fig
, parent_it
):
174 it
= self
._store
.iter_children(parent_it
)
175 while it
is not None:
176 name
= self
._store
.get_value(it
, 0)
177 item
= gtk
.MenuItem(name
)
178 item
.connect('activate', self
._signals
_menu
_item
_activated
,
179 (fig
, parent_it
, it
))
181 it
= self
._store
.iter_next(it
)
184 def _create_filename_menu(self
, fig
):
185 it
= self
._store
.get_iter_root()
190 while it
is not None:
191 filename
= self
._store
.get_value(it
, 0)
192 item
= gtk
.MenuItem(filename
)
193 item
.set_submenu(self
._create
_signals
_menu
(fig
, it
))
195 it
= self
._store
.iter_next(it
)
198 def _create_figure_popup_menu(self
, fig
):
200 if self
._current
_graph
is None:
201 item_nograph
= gtk
.MenuItem('No graph selected')
202 menu
.append(item_nograph
)
204 item_add
= gtk
.MenuItem('Add signal')
205 item_add
.set_submenu(self
._create
_filename
_menu
(fig
))
206 menu
.append(item_add
)
207 item_scale
= gtk
.MenuItem('Scale')
208 item_scale
.set_submenu(self
._create
_scale
_menu
(fig
))
209 menu
.append(item_scale
)
210 item_layout
= gtk
.MenuItem('Layout')
211 item_layout
.set_submenu(self
._create
_layout
_menu
(fig
))
212 menu
.append(item_layout
)
213 item_graph
= gtk
.MenuItem('Graph')
214 item_graph
.set_submenu(self
._create
_graph
_menu
(fig
))
215 menu
.append(item_graph
)
218 def _button_press(self
, widget
, event
):
219 if event
.button
== 3:
220 window
= widget
.parent
.parent
221 fig
= self
._windows
_to
_figures
[window
]
222 menu
= self
._create
_figure
_popup
_menu
(fig
)
224 menu
.popup(None, None, None, event
.button
, event
.time
)
226 #TODO: _windows_to_figures consistency...
227 # think of a better way to map events to Figure objects
228 def _row_activated(self
, widget
, path
, col
):
232 row
= self
._store
[path
]
233 self
._ctxt
.create({row
[0]: row
[1]})
234 fig
= self
._ctxt
.figures
[len(self
._ctxt
.figures
) - 1]
238 self
._windows
_to
_figures
[w
] = fig
239 w
.set_title('Figure %d' % self
._figcount
)
242 canvas
= FigureCanvas(fig
)
243 canvas
.connect('button-press-event', self
._button
_press
)
244 canvas
.mpl_connect('axes_enter_event', self
._axes
_enter
)
245 canvas
.mpl_connect('axes_leave_event', self
._axes
_leave
)
246 canvas
.mpl_connect('figure_enter_event', self
._figure
_enter
)
247 canvas
.mpl_connect('figure_leave_event', self
._figure
_leave
)
248 vbox
.pack_start(canvas
)
249 toolbar
= NavigationToolbar(canvas
, w
)
250 vbox
.pack_start(toolbar
, False, False)
254 def _axes_enter(self
, event
):
255 self
._current
_graph
= event
.inaxes
257 def _axes_leave(self
, event
):
258 # Unused for better user interaction
259 # self._current_graph = None
262 def _figure_enter(self
, event
):
263 self
._current
_figure
= event
.canvas
.figure
265 def _figure_leave(self
, event
):
266 # self._current_figure = None
269 if __name__
== '__main__':
271 main_loop
= gobject
.MainLoop()