def action_about(self, info): dialog = AboutDialog(image=find_icon('camera-video', size=64)) dialog.additions = [ 'Beams 0.1', u'© 2010, 2011, 2012 P. F. Chimento', 'MIT License' ] dialog.open()
def action_about(self, info): dialog = AboutDialog(image=find_icon("camera-video", size=64)) dialog.additions = ["Beams 0.1", u"© 2010, 2011, 2012 P. F. Chimento", "MIT License"] dialog.open()
class MainWindow(HasTraits): '''The main window for the Beams application.''' # Current folder for file dialog _current_folder = None camera = Instance(Camera) id_string = DelegatesTo('camera') resolution = DelegatesTo('camera') status = Str() screen = Instance(CameraImage, args=()) cmap = DelegatesTo('screen') display_frame_rate = Range(1, 60, 15) transform_plugins = List(Instance(TransformPlugin)) display_plugins = List(Instance(DisplayPlugin)) acquisition_thread = Instance(AcquisitionThread) # default: None processing_thread = Instance(ProcessingThread) # default: None processing_queue = Instance(queue.Queue, kw={'maxsize': MAX_QUEUE_SIZE}) cameras_dialog = Instance(CameraDialog, args=()) # Actions about = Action(name='&About...', tooltip='About Beams', image=find_icon('about'), action='action_about') save = Action(name='&Save Image', accelerator='Ctrl+S', tooltip='Save the current image to a file', image=find_icon('save'), action='action_save') quit = Action(name='&Quit', accelerator='Ctrl+Q', tooltip='Exit the application', image=find_icon('quit'), action='_on_close') choose_camera = Action(name='Choose &Camera...', tooltip='Choose from a number of camera plugins', action='action_choose_camera') take_video = Action(name='Take &Video', style='toggle', tooltip='Start viewing the video feed from the camera', image=find_icon('camera-video'), action='action_take_video') take_photo = Action(name='Take &Photo', tooltip='Take one snapshot from the camera', image=find_icon('camera-photo'), action='action_take_photo', enabled_when='self.take_video.checked == False') find_resolution = Button() view = View( VGroup( HSplit( Tabbed( VGroup(Item('id_string', style='readonly', label='Camera'), Item('resolution', style='readonly', format_str=u'%i \N{multiplication sign} %i'), Group(Item('camera', show_label=False, style='custom'), label='Camera properties', show_border=True), label='Camera'), VGroup(Item('cmap', label='Color scale', editor=EnumEditor( values={ None: '0:None (image default)', gray: '1:Grayscale', bone: '2:Bone', pink: '3:Copper', jet: '4:Rainbow (considered harmful)', isoluminant: '5:Isoluminant', awesome: '6:Low-intensity contrast' })), Item('screen', show_label=False, editor=ColorMapEditor(width=256)), Item('display_frame_rate'), label='Video'), # FIXME: mutable=False means the items can't be deleted, # added, or rearranged, but we do actually want them to # be rearranged. VGroup(Item('transform_plugins', show_label=False, editor=ListEditor(style='custom', mutable=False)), label='Transform'), VGroup(Item('display_plugins', show_label=False, editor=ListEditor(style='custom', mutable=False)), label='Math')), Item('screen', show_label=False, width=640, height=480, style='custom')), Item('status', style='readonly', show_label=False)), menubar=MenuBar( # vertical bar is undocumented but it seems to keep the menu # items in the order they were specified in Menu('|', save, '_', quit, name='&File'), Menu(name='&Edit'), Menu(name='&View'), Menu('|', choose_camera, '_', take_photo, take_video, name='&Camera'), Menu(name='&Math'), Menu(about, name='&Help')), toolbar=ToolBar('|', save, '_', take_photo, take_video), title='Beams', resizable=True, handler=MainHandler) def _find_resolution_fired(self): return self.view.handler.action_find_resolution(None) def _display_frame_rate_changed(self, value): self.processing_thread.update_frequency = value def _transform_plugins_default(self): plugins = [] for name in ['Rotator', 'BackgroundSubtract']: module = __import__(name, globals(), locals(), [name]) plugins.append(getattr(module, name)()) return plugins def _display_plugins_default(self): plugins = [] for name in [ 'BeamProfiler', 'MinMaxDisplay', 'DeltaDetector', 'Centroid' ]: module = __import__(name, globals(), locals(), [name]) plugins.append(getattr(module, name)(screen=self.screen)) return plugins def __init__(self, **traits): super(MainWindow, self).__init__(**traits) # Build the camera selection dialog box self.cameras_dialog.on_trait_change(self.on_cameras_response, 'closed') self.on_cameras_response() self.processing_thread = ProcessingThread(self, self.processing_queue, self.display_frame_rate) self.processing_thread.start() def on_cameras_response(self): plugin_obj = self.cameras_dialog.get_plugin_object() try: self.select_plugin(plugin_obj) except ImportError: # some module was not available, select the dummy error( None, 'Loading the {} camera plugin failed. ' 'Taking you back to the dummy plugin.'.format( plugin_obj['name'])) self.cameras_dialog.select_fallback() info = self.cameras_dialog.get_plugin_info() self.select_plugin(*info) # Select camera plugin def select_plugin(self, plugin_obj): # Set up image capturing self.camera = plugin_obj() try: self.camera.open() except CameraError: error(None, 'No camera was detected. Did you forget to plug it in?') sys.exit()
class CameraDialog(HasTraits): """Dialog for selecting the camera plugin.""" cameras = List(Tuple(Str, Str, Str)) camera_selection = Int() closed = Event() # UI about_plugin = Action(name='About', action='on_about_plugin', icon=find_icon('about')) view = View( Item('cameras', show_label=False, editor=ListStrEditor( adapter=_CameraDescriptionAdapter(), selected_index='camera_selection', editable=False, multi_select=False)), buttons=[about_plugin, CloseAction], title='Available Camera Plugins', resizable=True, width=400, height=200, handler=_CameraDialogHandler()) # Public def get_plugin_object(self): """For the selected plugin, returns a tuple of the module name to import and the class name to construct in order to get a Camera object.""" # Find the selected plugin plugin_id = self.cameras[self.camera_selection][0] # This should not fail, because only plugins which have all the requred # dependencies installed should be able to be selected try: return self.plugins[plugin_id].load() except ImportError: assert 0, ("A plugin was selected that didn't have all its " + "dependencies installed. This should not happen.") def __init__(self, **traits): super(CameraDialog, self).__init__(**traits) # Load the plugins self.plugins = pkg_resources.get_entry_map('beams', 'camera_plugins') if 'dummy' not in self.plugins.keys(): raise IOError("Plugin directory isn't configured properly") # Try to select the webcam try: self._select_plugin_by_name('webcam') except ValueError: self.select_fallback() def _cameras_default(self): # Construct list store of plugins retval = [] for plugin in self.plugins.keys(): try: info = self.plugins[plugin].load().plugin_info except ImportError: # A required module was not found for that plugin, ignore it continue retval += [(plugin, info['name'], info['description'])] return retval def _select_plugin_by_name(self, name): """Select a plugin by name""" for ix, cam in enumerate(self.cameras): if cam[0] == name: self.camera_selection = ix return raise ValueError('Plugin {} not in list'.format(name)) def select_fallback(self): """Select the dummy plugin as a fallback""" try: self._select_plugin_by_name('dummy') except ValueError: assert 0, 'Dummy plugin was not in list. Should not happen.'