def __init__(self, scope, tile_dir, n_tiles=10, tile_spacing=None, dwelltime=1, background=0, evtLog=False, trigger=False, base_tile_size=256): if tile_spacing is None: fs = np.array(scope.frameWrangler.currentFrame.shape[:2]) #calculate tile spacing such that there is 20% overlap. tile_spacing = 0.8 * fs * np.array(scope.GetPixelSize()) pointScanner.PointScanner.__init__(self, scope=scope, pixels=n_tiles, pixelsize=tile_spacing, dwelltime=dwelltime, background=background, avg=False, evtLog=evtLog, trigger=trigger, stop_on_complete=True) self._tiledir = tile_dir self._base_tile_size = base_tile_size self._flat = None #currently not used self._last_update_time = 0 self.on_stop = dispatch.Signal() self.progress = dispatch.Signal()
def __init__(self): self._interfaces = set([ CLIENT, CLIENT_HANDLER, CLIENT_INTERFACE_REQUESTS, PROPERTIES_IFACE, CLIENT_APPROVER ]) bus = dbus.Bus() bus_name = dbus.service.BusName(SUGAR_CLIENT_SERVICE, bus=bus) dbus.service.Object.__init__(self, bus_name, SUGAR_CLIENT_PATH) DBusProperties.__init__(self) self._implement_property_get( CLIENT, { 'Interfaces': lambda: list(self._interfaces), }) self._implement_property_get( CLIENT_HANDLER, { 'HandlerChannelFilter': self.__get_filters_cb, }) self._implement_property_get( CLIENT_APPROVER, { 'ApproverChannelFilter': self.__get_filters_cb, }) self.got_channel = dispatch.Signal() self.got_dispatch_operation = dispatch.Signal()
def __init__(self, testFrameSize=TEST_FRAME_SIZE, serverfilter=''): self.testData = (100 * np.random.rand(*testFrameSize)).astype('uint16') self.onFrame = dispatch.Signal(['frameData']) self.spoolProgress = dispatch.Signal(['percent']) self.mdh = MetaDataHandler.NestedClassMDHandler() self.serverfilter = serverfilter
def __init__(self, *args, **kwargs): HasTraits.__init__(self, *args, **kwargs) self.namespace = {} # we open hdf files and don't necessarily read their contents into memory - these need to be closed when we # either delete the recipe, or clear the namespace self._open_input_files = [] self.recipe_changed = dispatch.Signal() self.recipe_executed = dispatch.Signal()
def __init__(self, _cam, _ds = None, event_loop=None): #wx.EvtHandler.__init__(self) #self.timer = wx.Timer(self) #self.Bind(wx.EVT_TIMER, self.Notify) if event_loop is None: from PYME.ui import mytimer self._event_loop = mytimer else: self._event_loop = event_loop self.timer = self._event_loop.SingleTargetTimer(self.Notify) self.currentFrame = _ds self.cam = _cam self.aqOn = False #list of functions to call to see if we ought to wait on any hardware self.HardwareChecks = [] #should we start a new exposure on the next timer check? self.needExposureStart = False #did the buffer overflow? self.bufferOverflowed = False self.tLastFrame=0 self.tThisFrame=0 self.nFrames = 0 self.n_frames_in_group=0 self.tl=0 self.inNotify = False #Signals ########################## # these allow other files to listen to key events happingin within the acquisiotn #new style signals - these will replace the WantFrameNotification etc ... #which are currently being kept for backwards compatibility self.onFrame = dispatch.Signal(['frameData']) #called each time a new frame appears in our buffer self.onFrameGroup = dispatch.Signal() #called on each new frame group (once per polling interval) - use for updateing GUIs etc. self.onStop = dispatch.Signal() self.onStart = dispatch.Signal() # should the thread which polls the camera still be running? self._poll_camera = True self._current_frame_lock = threading.Lock() self._poll_lock = threading.Lock() self._poll_thread = threading.Thread(target=self._poll_loop) self._poll_thread.start()
def __init__(self, filename=None, visFr=None): self.filter = None self.mapping = None self.colourFilter = None self.events = None self.recipe = ModuleCollection(execute_on_invalidation=True) self.recipe.recipe_executed.connect(self.Rebuild) self.selectedDataSourceKey = None self.filterKeys = { 'error_x': (0, 30), 'error_y': (0, 30), 'A': (5, 20000), 'sig': (95, 200) } self.blobSettings = BlobSettings() self.objects = None self.imageBounds = ImageBounds(0, 0, 0, 0) self.mdh = MetaDataHandler.NestedClassMDHandler() self.Triangles = None self.edb = None self.Quads = None self.GeneratedMeasures = {} self.QTGoalPixelSize = 5 self._extra_chan_num = 0 self.filesToClose = [] self.ev_mappings = {} #define a signal which a GUI can hook if the pipeline is rebuilt (i.e. the output changes) self.onRebuild = dispatch.Signal() #a cached list of our keys to be used to decide whether to fire a keys changed signal self._keys = None #define a signal which can be hooked if the pipeline keys have changed self.onKeysChanged = dispatch.Signal() self.ready = False #self.visFr = visFr if not filename is None: self.OpenFile(filename)
def __init__(self, *args, **kwargs): try: self.orientation = kwargs.pop('orientation') except KeyError: self.orientation = wx.VERTICAL try: self.padding = kwargs.pop('padding') except KeyError: self.padding = 5 self._stretch_sizer = kwargs.pop('bottom_spacer', True) self._one_pane_active = kwargs.pop('single_active_pane', False) wx.Panel.__init__(self, *args, **kwargs) if self.orientation == wx.VERTICAL: self.sizerflags = wx.EXPAND #| wx.BOTTOM else: self.sizerflags = wx.EXPAND #| wx.RIGHT self.priorities = [] self.panes = [] self.sizer = wx.BoxSizer(self.orientation) self.SetSizer(self.sizer) self._in_fold1 = False self.fold_signal = dispatch.Signal() self.Bind(wx.EVT_SIZE, self.OnResize) self.Bind(EVT_CMD_PANEL_FOLD, self.OnResize)
def __init__(self, *args, **kwargs): try: self.orientation = kwargs.pop('orientation') except KeyError: self.orientation = wx.VERTICAL try: self.padding = kwargs.pop('padding') except KeyError: self.padding = 5 wx.Panel.__init__(self, *args, **kwargs) if self.orientation == wx.VERTICAL: self.sizerflags = wx.EXPAND #| wx.BOTTOM else: self.sizerflags = wx.EXPAND #| wx.RIGHT self.priorities = [] self.panes = [] self.sizer = wx.BoxSizer(self.orientation) self.SetSizer(self.sizer) self.fold_signal = dispatch.Signal()
def __init__(self, pipeline, method='points', ds_name='', cmap='gist_rainbow', clim=[0, 1], alpha=1.0, visible=True, method_args={}): self._pipeline = pipeline #self._namespace=getattr(pipeline, 'namespace', {}) #self.dsname = None self.engine = None self.cmap = cmap self.clim = clim self.alpha = alpha self.visible = visible self.on_update = dispatch.Signal() self.on_trait_change(lambda: self.on_update.send(self), 'visible') self.on_trait_change(self.update, 'cmap, clim, alpha, dsname') self.on_trait_change(self._set_method, 'method') #self.set_datasource(ds_name) self.dsname = ds_name self._eng_params = dict(method_args) self.method = method self._pipeline.onRebuild.connect(self.update)
def __init__(self): self.LIST_CHANGED_SIGNAL = dispatch.Signal() self._visibility_mask = [] self._names = {} self._rois = [] self._partial_ensemble_parameters = np.array([])
def __init__(self, key, getFcn=None, setFcn=None, needCamRestart=False): """Define a state-change handler for a give state key, based on supplied get and set functions which interact with the underlying hardware. This wrapper class serves two functions - a) allowing the get and set methods to be stored under a single dictionary key in the StateManager, and b) making sure a signal is fired when the state changes. Parameters ---------- key : string The hardware key - e.g. "Positioning.x", or "Lasers.405.Power". This will also be how the hardware state is recorder in the metadata. getFcn : function The function to call to get the value of the parameter. Should take one parameter which is the value to get setFcn : function The function to call to set the value of the parameter. Should take one parameter which is the value to set. Not providing a setFcn results in a read-only property. needCamRestart : bool Does this absolutely need a camera restart (e.g. we are changing which camera we are using). Will override other preferences. """ self.getValue = getFcn self.setFcn = setFcn self.key = key self.needCamRestart = needCamRestart self.onChange = dispatch.Signal()
def __init__(self, _chans, _cam, _shutters, _ds=None): wx.EvtHandler.__init__(self) self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.Notify) self.chans = _chans #self.hwChans = _chans.hw #self.numHWChans = len(_chans.hw) #self.cols = _chans.cols self.dsa = _ds self.cam = _cam self.shutters = _shutters self.loopnuf = 0 self.aqOn = False #lists of functions to call on a new frame, and when the aquisition ends #self.WantFrameNotification = [] #self.WantStopNotification = [] #self.WantStartNotification = [] #list of functions to call to see if we ought to wait on any hardware self.HardwareChecks = [] #should we start a new exposure on the next timer check? self.needExposureStart = False self.tLastFrame = 0 self.tThisFrame = 0 self.nFrames = 0 self.tl = 0 self.inNotify = False self.zPos = 0 #will be needed to allow the display load to be minimised by, e.g. only updating display once per poll rather than once per frame #self.WantFrameGroupNotification = [] #Signals ########################## # these allow other files to listen to key events happingin within the acquisiotn #new style signals - these will replace the WantFrameNotification etc ... #which are currently being kept for backwards compatibility self.onFrame = dispatch.Signal( ['frameData']) #called each time a new frame appears in our buffer self.onFrameGroup = dispatch.Signal( ) #called on each new frame group (once per polling interval) - use for updateing GUIs etc. self.onStop = dispatch.Signal() self.onStart = dispatch.Signal()
def __init__(self): self.analysisMDH = MetaDataHandler.NestedClassMDHandler() self.onMetadataChanged = dispatch.Signal() self.propagateToAcquisisitonMetadata = False MetaDataHandler.provideStartMetadata.append(self.genStartMetadata)
def __init__(self, scope, handlers={}): self._stateHandlers = {} self._cachedStates = {} self._stateHandlers.update(handlers) self.scope = weakref.ref(scope) self.stateChanged = dispatch.Signal()
def __init__(self, scope, defDir=genHDFDataFilepath(), defSeries='%(day)d_%(month)d_series'): """Initialise the spooling controller. Parameters ---------- scope : microscope instance The currently active microscope class (see microscope.py) defDir : string pattern The default directory to save data to. Any keys of the form `%(<key>)` will be substituted using the values defined in `PYME.fileUtils.nameUtils.dateDict` defSeries : string pattern This specifies a pattern for file naming. Keys will be substituted as for `defDir` """ self.scope = scope self.spoolType = 'Queue' #dtn = datetime.datetime.now() #dateDict = {'username' : win32api.GetUserName(), 'day' : dtn.day, 'month' : dtn.month, 'year':dtn.year} self._user_dir = None self._base_dir = nameUtils.get_local_data_directory() self._subdir = nameUtils.get_spool_subdir() self.seriesStub = defSeries % nameUtils.dateDict self.seriesCounter = 0 self._series_name = None self.protocol = prot.NullProtocol self.protocolZ = prot.NullZProtocol self.onSpoolProgress = dispatch.Signal() self.onSpoolStart = dispatch.Signal() self.onSpoolStop = dispatch.Signal() self._analysis_launchers = queue.Queue(3) self.compressionSettings = HTTPSpooler.defaultCompSettings
def __init__(self, use_shaders=False): self._new_layers = PYME.config.get('VisGUI-new_layers', False) self.viewMode = 'points' #one of points, triangles, quads, or voronoi #self.colData = 't' self.pointDisplaySettings = pointSettingsPanel.PointDisplaySettings() self.pointDisplaySettings.on_trait_change(self.RefreshView) self.quadTreeSettings = quadTreeSettings.QuadTreeSettings() self.quadTreeSettings.on_trait_change(self.RefreshView) self.pipeline.blobSettings.on_trait_change(self.RefreshView) self.pipeline.onRebuild.connect(self.RefreshView) #initialize the gl canvas if isinstance(self, wx.Window): win = self else: win = self.dsviewer gl_pan = wx.Panel(win) sizer = wx.BoxSizer(wx.VERTICAL) if not use_shaders: self.glCanvas = gl_render.LMGLCanvas(gl_pan) else: from PYME.LMVis.gl_render3D_shaders import LMGLShaderCanvas, LegacyGLCanvas if self._new_layers: #use stripped down version self.glCanvas = LMGLShaderCanvas(gl_pan) else: self.glCanvas = LegacyGLCanvas(gl_pan) sizer.Add(self.create_tool_bar(gl_pan), 0, wx.EXPAND, 0) sizer.Add(self.glCanvas, 5, wx.EXPAND, 0) gl_pan.SetSizerAndFit(sizer) win.AddPage(page=gl_pan, caption='View')#, select=True) #self.glCanvas.setCMap(pylab.cm.gist_rainbow) #pylab.cm.hot #self.rec_gui = recipeGui. #win.AddPage(page=self.glCanvas, caption='View')#, select=True) self.refv = False self._legacy_layer = None self.layer_added = dispatch.Signal() renderers.renderMetadataProviders.append(self.SaveMetadata) self.use_shaders = use_shaders wx.CallLater(100, self.OnIdle)
def __init__(self, scope, tile_dir, n_tiles=10, tile_spacing=None, dwelltime=1, background=0, evtLog=False, trigger=False, base_tile_size=256, return_to_start=True): """ :param return_to_start: bool Flag to toggle returning home at the end of the scan. False leaves scope position as-is on scan completion. """ if tile_spacing is None: fs = np.array(scope.frameWrangler.currentFrame.shape[:2]) #calculate tile spacing such that there is 20% overlap. tile_spacing = 0.8 * fs * np.array(scope.GetPixelSize()) pointScanner.PointScanner.__init__(self, scope=scope, pixels=n_tiles, pixelsize=tile_spacing, dwelltime=dwelltime, background=background, avg=False, evtLog=evtLog, trigger=trigger, stop_on_complete=True, return_to_start=return_to_start) self._tiledir = tile_dir self._base_tile_size = base_tile_size self._flat = None #currently not used self._last_update_time = 0 self.on_stop = dispatch.Signal() self.progress = dispatch.Signal()
def __init__(self, scope): self.scope = scope self.stackSettings = scope.stackSettings self.off = 0 self.sc = 100 self.sqrt = False self.frameNum = 0 #self.ds = scope.frameWrangler.currentFrame self.shape_x, self.shape_y = scope.frameWrangler.currentFrame.shape[:2] self.running = False #legacy signalling - don't use in new code. #self.WantFrameNotification = [] #self.WantTickNotification = [] #These signals should instead of the notification lists above self.onStack = dispatch.Signal() #dispatched on completion of a stack self.onSingleFrame = dispatch.Signal( ) #dispatched when a frame is ready
def __init__(self, filename, frameSource, protocol=p.NullProtocol, guiUpdateCallback=None, fakeCamCycleTime=None, maxFrames=p.maxint, **kwargs): """Create a new spooler. Parameters ---------- scope : PYME.Acquire.microscope.microscope object The microscope providing the data filename : string The file into which to spool frameSource : dispatch.Signal object A source of frames we can subscribe to. It should implement a "connect" method allowing us to register a callback and then call the callback with the frame data in a "frameData" kwarg. protocol : PYME.Acquire.protocol.TaskListProtocol object The acquisition protocol guiUpdateCallback : function a function to call when the spooling GUI needs updating """ global timeFcn #self.scope = scope self.filename = filename self.frameSource = frameSource self.guiUpdateCallback = guiUpdateCallback self.protocol = protocol self.maxFrames = maxFrames self.onSpoolStop = dispatch.Signal() #if we've got a fake camera - the cycle time will be wrong - fake our time sig to make up for this #if scope.cam.__class__.__name__ == 'FakeCamera': # timeFcn = self.fakeTime self._last_gui_update = 0 self.spoolOn = False self.imNum = 0 self._spooler_uuid = uuid.uuid4() if not fakeCamCycleTime is None: self.fakeCamCycleTime = fakeCamCycleTime timeFcn = self.fakeTime
def __init__(self, pipeline, method='wireframe', dsname='', context=None, **kwargs): EngineLayer.__init__(self, context=context, **kwargs) self._pipeline = pipeline self.engine = None self.cmap = 'gist_rainbow' self.x_key = 'x' # TODO - make these traits? self.y_key = 'y' self.z_key = 'z' self.xn_key = 'xn' self.yn_key = 'yn' self.zn_key = 'zn' self._bbox = None # define a signal so that people can be notified when we are updated (currently used to force a redraw when # parameters change) self.on_update = dispatch.Signal() # define responses to changes in various traits self.on_trait_change(self._update, 'vertexColour') self.on_trait_change(lambda: self.on_update.send(self), 'visible') self.on_trait_change(self.update, 'cmap, clim, alpha, dsname, normal_mode') self.on_trait_change(self._set_method, 'method') # update any of our traits which were passed as command line arguments self.set(**kwargs) # update datasource and method self.dsname = dsname if self.method == method: #make sure we still call _set_method even if we start with the default method self._set_method() else: self.method = method # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update # ourselves if not self._pipeline is None: try: self._pipeline.onRebuild.connect(self.update) except AttributeError: pass
def __init__(self, datasource, xp=0, yp=0, zp=0, aspect=1): self.WantChangeNotification = [] # MyWeakSet() #[] self.Chans = [] self.Gains = [] self.Offs = [] self.cmaps = [] self.names = [] self.show = [] self._xp = 0 self._yp = 0 self._zp = 0 self.maximumProjection = False self.colourMax = False self.cmax_offset = 0.0 self.cmax_scale = 1.0 self._complexMode = 'coloured' self.inOnChange = False self.syncedWith = [] self.SetDataStack(datasource) self.SetAspect(aspect) self.ResetSelection() self.orientation = self.UPRIGHT self.slice = self.SLICE_XY self.scale = 0 self.leftButtonAction = self.ACTION_POSITION self.selectionMode = self.SELECTION_RECTANGLE self.selectionWidth = 1 self.showSelection = False #signals (currently just for selection end # this lets people know that we've made a selection. Used to allow modification of the selection by some filter # e.g. using active contours in the annotation module self.on_selection_end = dispatch.Signal() self.overlays = []
def __init__(self, pipeline, method='points', dsname='', context=None, **kwargs): EngineLayer.__init__(self, context=context, **kwargs) self._pipeline = pipeline self.engine = None self.cmap = 'gist_rainbow' self.x_key = 'x' #TODO - make these traits? self.y_key = 'y' self.z_key = 'z' self.xn_key = 'xn' self.yn_key = 'yn' self.zn_key = 'zn' self._bbox = None # define a signal so that people can be notified when we are updated (currently used to force a redraw when # parameters change) self.on_update = dispatch.Signal() # define responses to changes in various traits self.on_trait_change(self._update, 'vertexColour') self.on_trait_change(lambda: self.on_update.send(self), 'visible') self.on_trait_change(self.update, 'cmap, clim, alpha, dsname, point_size') self.on_trait_change(self._set_method, 'method') # update any of our traits which were passed as command line arguments self.set(**kwargs) # update datasource name and method #logger.debug('Setting dsname and method') self.dsname = dsname self.method = method self._set_method() # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update # ourselves if not self._pipeline is None: self._pipeline.onRebuild.connect(self.update)
def __init__(self, pipeline, method='image', dsname='', display_opts=None, context=None, **kwargs): EngineLayer.__init__(self, context=context, **kwargs) self._pipeline = pipeline self.engine = None self.cmap = 'gray' self._bbox = None self._do = display_opts #a dh5view display_options instance - if provided, this over-rides the the clim, cmap properties self._im_key = None # define a signal so that people can be notified when we are updated (currently used to force a redraw when # parameters change) self.on_update = dispatch.Signal() # define responses to changes in various traits #self.on_trait_change(self._update, 'vertexColour') self.on_trait_change(lambda: self.on_update.send(self), 'visible') self.on_trait_change(self.update, 'cmap, clim, alpha, dsname') self.on_trait_change(self._set_method, 'method') # update any of our traits which were passed as command line arguments self.set(**kwargs) # update datasource and method self.dsname = dsname if self.method == method: #make sure we still call _set_method even if we start with the default method self._set_method() else: self.method = method # if we were given a pipeline, connect ourselves to the onRebuild signal so that we can automatically update # ourselves if (not self._pipeline is None) and hasattr(pipeline, 'onRebuild'): self._pipeline.onRebuild.connect(self.update)
def __init__(self, scope): """Initialise our action manager Parameters ---------- scope : PYME.Acquire.microscope.microscope object The microscope. The function object to call for an action should be accessible within the scope namespace, and will be resolved by calling eval('scope.functionName') """ self.actionQueue = Queue.PriorityQueue() self.scope = weakref.ref(scope) #this will be assigned to a callback to indicate if the last task has completed self.isLastTaskDone = None self.paused = False self.currentTask = None self.onQueueChange = dispatch.Signal() self._timestamp = 0
def __init__(self, imageMdh=None, tq=None): self.analysisMDH = MetaDataHandler.NestedClassMDHandler(imageMdh) self.onImagesPushed = dispatch.Signal() self.onMetaDataChange = dispatch.Signal() self.tq = tq
import dispatch event_received = dispatch.Signal( providing_args=['aggregate_name', 'aggregate_id', 'payload']) event_pre_save = dispatch.Signal(providing_args=[ 'aggregate_name', 'aggregate_id', 'payload', 'event_name', 'version', ]) event_post_save = dispatch.Signal(providing_args=['event'])
from __future__ import print_function import time from subprocess import Popen from datetime import datetime import dispatch from biothings.utils.common import timesofar from utils.common import src_path from biothings.utils.mongo import src_clean_archives, target_clean_collections from dataload.dispatch import (check_mongo, get_process_info, src_dump, mark_upload_started, mark_upload_done) from dataload.dispatch import dispatch as dispatch_src_upload from config import DATA_WWW_ROOT_URL source_update_available = dispatch.Signal(providing_args=["src_to_update"]) source_upload_success = dispatch.Signal(providing_args=["src_name"]) source_upload_failed = dispatch.Signal(providing_args=["src_name"]) genedoc_merged = dispatch.Signal() es_indexed = dispatch.Signal() try: from utils.common import hipchat_msg except: hipchat_msg = None class GeneDocDispatcher: running_processes_upload = {} idle = True
def __init__(self): #self.image = image self.onFrame = dispatch.Signal(['frameData']) self.spoolProgress = dispatch.Signal(['percent'])
def __init__(self): """ Setups signaling object. """ super(Publisher, self).__init__() self._signal = dispatch.Signal()
def __init__(self, parent, filterKeys, dataSource=None): """ Parameters ---------- parent : wx.Window filterKeys : dict Dictionary keys dataSource : function function to call to get the current data source """ wx.Panel.__init__(self, parent) self.filterKeys = filterKeys self._dataSource = dataSource self.on_filter_changed = dispatch.Signal() #GUI stuff vsizer = wx.BoxSizer(wx.VERTICAL) self.lFiltKeys = wx.ListCtrl( self, -1, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.SUNKEN_BORDER, size=(-1, 25 * (max(len(self.filterKeys.keys()) + 1, 5)))) self.lFiltKeys.InsertColumn(0, 'Key') self.lFiltKeys.InsertColumn(1, 'Min') self.lFiltKeys.InsertColumn(2, 'Max') self.populate() self.lFiltKeys.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.lFiltKeys.SetColumnWidth(1, wx.LIST_AUTOSIZE) self.lFiltKeys.SetColumnWidth(2, wx.LIST_AUTOSIZE) # only do this part the first time so the events are only bound once if not hasattr(self, "ID_FILT_ADD"): self.ID_FILT_ADD = wx.NewId() self.ID_FILT_DELETE = wx.NewId() self.ID_FILT_EDIT = wx.NewId() self.Bind(wx.EVT_MENU, self.OnFilterAdd, id=self.ID_FILT_ADD) self.Bind(wx.EVT_MENU, self.OnFilterDelete, id=self.ID_FILT_DELETE) self.Bind(wx.EVT_MENU, self.OnFilterEdit, id=self.ID_FILT_EDIT) # for wxMSW self.lFiltKeys.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnFilterListRightClick) # for wxGTK self.lFiltKeys.Bind(wx.EVT_RIGHT_UP, self.OnFilterListRightClick) self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnFilterItemSelected) self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnFilterItemDeselected) self.lFiltKeys.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnFilterEdit) vsizer.Add(self.lFiltKeys, 1, wx.ALL | wx.EXPAND, 0) #self.stNumFiltered = wx.StaticText(self, -1, '') #vsizer.Add(self.stNumFiltered, 0, wx.ALL | wx.EXPAND, 2) self.SetSizerAndFit(vsizer)