def loadMonitors(self): self.active_monitors = {} resolution = options.GetOption("Resolution") data_folder = options.GetOption("Data_Folder") monitorsData = options.getMonitorsData() for mn in monitorsData: m = monitorsData[mn] track_type = ['DISTANCE', 'VBS', 'XY_COORDS'].index(m['track_type']) if type(m['source']) == int: source = int(m['source']) - 1 else: source = m['source'] output_file = m['outputfile'] or os.path.join( data_folder, 'Monitor%02d.txt' % mn) self.active_monitors[mn] = pysolovideo.Monitor() success = self.active_monitors[mn].setSource(source, resolution) if success: self.active_monitors[mn].setTracking(True, track_type, m['mask_file'], output_file) self.active_monitors[mn].SDserialPort = m['serial_port'] self.active_monitors[mn].inactivity_threshold = m[ 'inactivity_threshold'] or None #self.changeIcon(mn, 1) else: #self.changeIcon(mn, -1) pass pysolovideo.MONITORS = self.active_monitors
def onRefresh(self): monitor_number = options.GetOption("Monitors") if self.mon_num != monitor_number: self.scrollThumbnails.updateMonitors(self.mon_num, monitor_number) tn_size = options.GetOption("ThumbnailSize") if self.thumb_size != tn_size: self.scrollThumbnails.updateThumbs(self.thumb_size, tn_size) self.PanelOneSizer.Layout() self.Layout()
def onLoadMask(self, event): """ Load Mask from file """ print('Load Mask Function') # temporary debug print wildcard = "PySolo Mask (*.msk) | *.msk | " \ "All files (*.*)|*.*" print('before filedialog') # temporary debug print dlg = wx.FileDialog(self, message="Choose a file", defaultDir=options.GetOption("Mask_Folder"), defaultFile="", wildcard=wildcard, style=wx.FD_OPEN | wx.FD_CHANGE_DIR) print('after filedialog') # temporary debug print if dlg.ShowModal() == wx.ID_OK: print('showmodal is true') # temporary debug print path = dlg.GetPath() print('Load Path = ' + path) # temporary debug print self.fsPanel.mon.saveROIS( path) # load set to save temporarily since load isn't working self.currentMaskTXT.SetValue(os.path.split(path)[1]) print('done') # temporary debug print dlg.Destroy()
def onSaveMask(self, event): # temporary debug print print( 'Current Mask Name = ' + self.currentMaskTXT.GetValue() ) # each switch between file types adds another .msk to the filename wildcard = "PySolo Mask (*.msk) | *.msk |" \ "All files (*.*)|*.*" print('wildcard = ' + wildcard) # temporary debug print dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=options.GetOption("Mask_Folder"), defaultFile=self.currentMaskTXT.GetValue(), wildcard=wildcard, style=wx.SAVE | wx.FD_OVERWRITE_PROMPT) print('Current Mask Name = ' + self.currentMaskTXT.GetValue()) # temporary debug print # dlg.SetFilterIndex(2) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() print('save path = ' + path) # temporary debug print self.fsPanel.mon.saveROIS(path) self.currentMaskTXT.SetValue(os.path.split(path)[1]) dlg.Destroy()
def onRefresh(self): """ Called when the options dialog has been closed with an "OK" """ # Determine what changes must be made old_mons = self.mon_num # How many monitors we have right now old_cams = self.num_cams # How many cameras we have right now self.mon_num = options.GetOption( "Monitors") # Get desired number of monitors from config file self.num_cams = options.GetOption( "Webcams") # Get desired number of webcams from config file if old_mons != self.mon_num: # If current number of monitors doesn't match config file, update self.updateMonNum(old_mons) if old_cams != self.num_cams: # If current number of cameras doesn't match config file, update self.updateNumCams(old_cams)
def __init__(self, parent): wx.Panel.__init__(self, parent) monitor_number = options.GetOption("Monitors") tn_size = options.GetOption("ThumbnailSize") self.temp_source = '' self.source = '' self.sourceType = -1 self.scrollThumbnails = panelGridView(self, gridSize=monitor_number, thumbnailSize=tn_size) self.lowerPanel = panelConfigure(self) self.PanelOneSizer = wx.BoxSizer(wx.VERTICAL) self.PanelOneSizer.Add(self.scrollThumbnails, 1, wx.EXPAND, 0) self.PanelOneSizer.Add(self.lowerPanel, 0, wx.EXPAND, 0) self.SetSizer(self.PanelOneSizer)
def makePanel(self, parent, name): """ """ tp = wx.Panel(parent, -1, style=wx.TAB_TRAVERSAL) self.virtualw = wx.ScrolledWindow(tp) sz1 = wx.BoxSizer(wx.VERTICAL) titleFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) items = [] for option in options.getOptionsNames(name): option_name = option option_value = str(options.GetOption(option_name)) option_description = options.getOptionDescription(option_name) items.append( wx.StaticText(self.virtualw, -1, '\nSet value of the variable: %s' % option_name)) items[-1].SetFont(titleFont) items.append(wx.StaticText(self.virtualw, -1, option_description)) if "FOLDER" in option_name.upper(): items.append( filebrowse.DirBrowseButton(self.virtualw, -1, size=(400, -1), changeCallback=partial( self.__saveValue, option_name), startDirectory=".")) items.append((wx.StaticLine(self.virtualw), 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)) else: #for boolean first choice is always True, second choice always False items.append(wx.TextCtrl(self.virtualw, -1, value=option_value)) items[-1].Bind(wx.EVT_TEXT, partial(self.__saveValue, option_name)) items.append((wx.StaticLine(self.virtualw), 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)) sz1.AddMany(items) self.virtualw.SetSizer(sz1) sz1.Fit(self.virtualw) self.virtualw.SetScrollRate(20, 20) TreeBookPanelSizer = wx.BoxSizer() TreeBookPanelSizer.Add(self.virtualw, 1, wx.GROW | wx.EXPAND, 0) tp.SetSizer(TreeBookPanelSizer) return tp
def drawPanel(self): # Draw the main interface for child in self.GetChildren(): child.Destroy() self.mon_num = options.GetOption( "Monitors") # Get number of monitors from config file self.num_cams = options.GetOption( "Webcams") # Get number of cameras from config file monitorsData = options.getMonitorsData() self.monitorsData = monitorsData WebcamsList = [ 'Camera %02d' % (int(w) + 1) for w in range(self.num_cams) ] # Generate a list of cameras colLabels = [ 'Status', 'Monitor', 'Source', 'Mask', 'Output', 'Track type', 'Track', 'uptime', 'preview' ] tracktypes = ['DISTANCE', 'VBS', 'XY_COORDS'] # create layouts and their items mainSizer = wx.BoxSizer(wx.VERTICAL) self.drawMonitorGrid(self.mon_num, colLabels, WebcamsList, tracktypes) btnSizer = self.drawButtons( ) # The buttons that do not go with a particular monitor # Add monitor grid and buttons to main layout mainSizer.Add(self.gridSizer, 1, wx.EXPAND, 0) mainSizer.Add(btnSizer, 0, wx.ALL, 5) mainSizer.Layout() # Store sizers as global variables in order to update UI later self.mainSizer = mainSizer self.SetSizer( mainSizer) # Make the panel display the mainSizer and its contents self.Refresh()
def makePanel(self, parent, name): # Make a new panel tp = wx.Panel(parent, -1, style = wx.TAB_TRAVERSAL) # The panel contains a window, allowing us to scroll self.virtualw = wx.ScrolledWindow(tp) sz1 = wx.BoxSizer(wx.VERTICAL) titleFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) items = [] # Put all of the options on the page for option in options.getOptionsNames(name): option_name = option option_value= str(options.GetOption(option_name)) option_description = options.getOptionDescription(option_name) # Display option name and description items.append ( wx.StaticText(self.virtualw, -1, '\nSet value of the variable: %s' % option_name)) items[-1].SetFont(titleFont) items.append ( wx.StaticText(self.virtualw, -1, option_description) ) # If the option is regarding a folder, make a Browse button if "FOLDER" in option_name.upper(): items.append ( filebrowse.DirBrowseButton(self.virtualw, -1, size=(400, -1), changeCallback = partial(self.__saveValue, option_name), startDirectory="." )) items.append ( (wx.StaticLine(self.virtualw), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )) # Add a text field for the user to change the option else: #for boolean first choice is always True, second choice always False items.append ( wx.TextCtrl (self.virtualw, -1, value=option_value)) items[-1].Bind (wx.EVT_TEXT, partial (self.__saveValue, option_name) ) items.append ( (wx.StaticLine(self.virtualw), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 )) # Put all of them in a boxsizer sz1.AddMany (items) self.virtualw.SetSizer(sz1) sz1.Fit(self.virtualw) # fit to window self.virtualw.SetScrollRate(20,20) TreeBookPanelSizer = wx.BoxSizer() TreeBookPanelSizer.Add(self.virtualw, 1, wx.GROW | wx.EXPAND, 0) tp.SetSizer(TreeBookPanelSizer) return tp
def onLoadMask(self, event): """ Load Mask from file """ wildcard = "pySolo mask file (*.msk)|*.msk" dlg = wx.FileDialog(self, message="Choose a file", defaultDir=options.GetOption("Mask_Folder"), defaultFile="", wildcard=wildcard, style=wx.OPEN | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.fsPanel.mon.loadROIS(path) self.currentMaskTXT.SetValue(os.path.split(path)[1]) dlg.Destroy()
def onSaveMask(self, event): """ Save ROIs to File """ filename = '%s.msk' % self.monitor_name.replace(' ','_') wildcard = "pySolo mask file (*.msk)|*.msk" dlg = wx.FileDialog( self, message="Save file as ...", defaultDir=options.GetOption("Mask_Folder"), defaultFile=filename, wildcard=wildcard, style=wx.SAVE ) #dlg.SetFilterIndex(2) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.fsPanel.mon.saveROIS(path) self.currentMaskTXT.SetValue(os.path.split(path)[1]) dlg.Destroy() return path
def updateNumCams(self, old): """ Updates the camera combofilebrowser when the number of cameras changes """ WebcamsList = [ 'Camera %02d' % (int(w) + 1) for w in range(self.num_cams) ] i = 11 # Skip the labels, start with first monitor for mn in range(1, self.mon_num + 1): # For each monitor if not options.HasMonitor(mn): options.SetMonitor( mn) #If monitor does not exist in options we create it md = options.GetMonitor(mn) try: _, source = os.path.split(md['source']) except: source = 'Camera %02d' % (md['source']) self.gridSizer.Hide(i) self.gridSizer.Remove(i) # Remove the outdated dropdown menu self.gridSizer.Insert( i, # Insert a new dropdown menu in its place comboFileBrowser( self, wx.ID_ANY, size=(-1, -1), dialogTitle="Choose an Input video file", startDirectory=options.GetOption("Data_Folder"), value=source, choices=WebcamsList, fileMask="Video File (*.*)|*.*", browsevalue="Browse for video...", changeCallback=partial(self.onChangeDropDown, [mn, "source"])), 0, wx.ALL | wx.ALIGN_CENTER, 5) self.gridSizer.Layout() # Show changes on GUI i += 9 # Move to next monitor (gridsizer rows are 9 items wide)
def __init__(self, parent): """ """ wx.Panel.__init__(self, parent, wx.ID_ANY) self.monitor_name = '' self.fsPanel = previewPanel(self, size=options.GetOption("Resolution"), showtime=True) sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_2 = wx.BoxSizer(wx.HORIZONTAL) sizer_3 = wx.BoxSizer(wx.HORIZONTAL) sizer_4 = wx.BoxSizer(wx.VERTICAL) #Static box1: monitor input sb_1 = wx.StaticBox(self, -1, "Select Monitor")#, size=(250,-1)) sbSizer_1 = wx.StaticBoxSizer (sb_1, wx.VERTICAL) self.MonitorList = ['Monitor %s' % (int(m) + 1) for m in range(options.GetOption("Monitors"))] self.thumbnailNumber = wx.ComboBox(self, -1, size=(-1,-1) , choices=self.MonitorList, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) self.Bind(wx.EVT_COMBOBOX, self.onChangeMonitor, self.thumbnailNumber) self.sourceTXTBOX = wx.TextCtrl (self, -1, "No monitor selected", style=wx.TE_READONLY) sbSizer_1.Add ( self.thumbnailNumber, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) sbSizer_1.Add ( self.sourceTXTBOX, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) #Static box2: mask parameters sb_2 = wx.StaticBox(self, -1, "Mask Editing")#, size=(250,-1)) sbSizer_2 = wx.StaticBoxSizer (sb_2, wx.VERTICAL) fgSizer_1 = wx.FlexGridSizer( 0, 2, 0, 0 ) self.btnClear = wx.Button( self, wx.ID_ANY, label="Clear All") self.Bind(wx.EVT_BUTTON, self.fsPanel.ClearAll, self.btnClear) self.btnClearLast = wx.Button( self, wx.ID_ANY, label="Clear selected") self.Bind(wx.EVT_BUTTON, self.fsPanel.ClearLast, self.btnClearLast) self.AFValue = wx.TextCtrl (self, -1, "32") self.btnAutoFill = wx.Button( self, wx.ID_ANY, label="Auto Fill") self.Bind(wx.EVT_BUTTON, self.onAutoMask, self.btnAutoFill) #self.btnAutoFill.Enable(False) fgSizer_1.Add (self.btnClear) fgSizer_1.Add (self.btnClearLast) fgSizer_1.Add (self.AFValue) fgSizer_1.Add (self.btnAutoFill) sbSizer_2.Add (fgSizer_1) #Static box3: mask I/O sb_3 = wx.StaticBox(self, -1, "Mask File")#, size=(250,-1)) sbSizer_3 = wx.StaticBoxSizer (sb_3, wx.VERTICAL) self.currentMaskTXT = wx.TextCtrl (self, -1, "No Mask Loaded", style=wx.TE_READONLY) btnSizer_1 = wx.BoxSizer(wx.HORIZONTAL) self.btnLoad = wx.Button( self, wx.ID_ANY, label="Load Mask") self.Bind(wx.EVT_BUTTON, self.onLoadMask, self.btnLoad) self.btnSave = wx.Button( self, wx.ID_ANY, label="Save Mask") self.Bind(wx.EVT_BUTTON, self.onSaveMask, self.btnSave) self.btnSaveApply = wx.Button( self, wx.ID_ANY, label="Save and Apply") self.Bind(wx.EVT_BUTTON, self.onSaveApply, self.btnSaveApply) btnSizer_1.Add(self.btnLoad) btnSizer_1.Add(self.btnSave) btnSizer_1.Add(self.btnSaveApply) sbSizer_3.Add ( self.currentMaskTXT, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) sbSizer_3.Add (btnSizer_1, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) ## #Static box4: help sb_4 = wx.StaticBox(self, -1, "Help") sbSizer_4 = wx.StaticBoxSizer (sb_4, wx.VERTICAL) titleFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) instr = [ ('Left mouse button - single click outside ROI', 'Start dragging ROI. ROI will be a perfect rectangle'), ('Left mouse button - single click inside ROI', 'Select ROI. ROI turns red.'), ('Left mouse button - double click', 'Select corner of ROI.\nWill close ROI after fourth selection'), ('Middle mouse button - single click', 'Add currently selected ROI. ROI turns white.'), ('Right mouse button - click', 'Remove selected currently selected ROI'), ('Auto Fill', 'Will fill 32 ROIS (16x2) to fit under the last two\nselected points. To use select first upper left corner,\n then the lower right corner, then use "Auto Fill".') ] for title, text in instr: t = wx.StaticText(self, -1, title); t.SetFont(titleFont) sbSizer_4.Add( t, 0, wx.ALL, 2 ) sbSizer_4.Add(wx.StaticText(self, -1, text) , 0 , wx.ALL, 2 ) sbSizer_4.Add ( (wx.StaticLine(self)), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5 ) sizer_4.Add(sbSizer_1, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) sizer_4.Add(sbSizer_2, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) sizer_4.Add(sbSizer_3, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) sizer_4.Add(sbSizer_4, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND, 5 ) sizer_3.Add(self.fsPanel, 0, wx.LEFT|wx.TOP, 20 ) sizer_3.Add(sizer_4, 0, wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) sizer_1.Add(sizer_3, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) sizer_1.Add(sizer_2, 0, wx.ALIGN_CENTRE|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) self.SetSizer(sizer_1) print wx.Window.FindFocus() self.Bind( wx.EVT_CHAR, self.fsPanel.onKeyPressed )
# You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # %% import wx # GUI functions import os import numpy as np import cv2 # camera / video control import pysolovideo import pvg_options from sys import argv # file I/O from pvg_common import previewPanel, options x, y = options.GetOption("Resolution") # screen resolution # %% class panelLiveView(wx.Panel): """ Panel Number 2 Live view of selected camera """ # %% def __init__(self, parent): self.panel = wx.Panel.__init__(self, parent) self.fsPanel = previewPanel(self,
def __init__(self, parent): """ """ wx.Panel.__init__(self, parent, wx.ID_ANY, size=(-1, 300), style=wx.SUNKEN_BORDER | wx.TAB_TRAVERSAL) self.parent = parent self.thumbnail = None self.mask_file = None self.source = None self.sourceType = None self.track = None self.trackType = None lowerSizer = wx.BoxSizer(wx.HORIZONTAL) #Static box1 (LEFT) sb_1 = wx.StaticBox(self, -1, "Select Monitor") #, size=(250,-1)) sbSizer_1 = wx.StaticBoxSizer(sb_1, wx.VERTICAL) n_monitors = options.GetOption("Monitors") self.MonitorList = [ 'Monitor %s' % (int(m) + 1) for m in range(n_monitors) ] self.thumbnailNumber = wx.ComboBox(self, -1, size=(-1, -1), choices=self.MonitorList, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) self.Bind(wx.EVT_COMBOBOX, self.onChangingMonitor, self.thumbnailNumber) self.currentSource = wx.TextCtrl(self, -1, "No Source Selected", style=wx.TE_READONLY) btnSizer_1 = wx.BoxSizer(wx.HORIZONTAL) self.btnPlay = wx.Button(self, wx.ID_FORWARD, label="Play") self.btnStop = wx.Button(self, wx.ID_STOP, label="Stop") self.Bind(wx.EVT_BUTTON, self.onPlay, self.btnPlay) self.Bind(wx.EVT_BUTTON, self.onStop, self.btnStop) self.btnPlay.Enable(False) self.btnStop.Enable(False) self.applyButton = wx.Button(self, wx.ID_APPLY) self.applyButton.SetToolTip(wx.ToolTip("Apply and Save to file")) self.Bind(wx.EVT_BUTTON, self.onApplySource, self.applyButton) btnSizer_1.Add(self.btnPlay, 0, wx.ALIGN_LEFT | wx.ALL, 5) btnSizer_1.Add(self.btnStop, 0, wx.ALIGN_CENTER | wx.LEFT | wx.TOP | wx.DOWN, 5) btnSizer_1.Add(self.applyButton, 0, wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_1.Add(self.thumbnailNumber, 0, wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_1.Add( self.currentSource, 0, wx.EXPAND | wx.ALIGN_CENTRE | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_1.Add(btnSizer_1, 0, wx.EXPAND | wx.ALIGN_BOTTOM | wx.TOP, 5) lowerSizer.Add(sbSizer_1, 0, wx.EXPAND | wx.ALL, 5) #Static box2 (CENTER) sb_2 = wx.StaticBox(self, -1, "Select Video input") sbSizer_2 = wx.StaticBoxSizer(sb_2, wx.VERTICAL) grid2 = wx.FlexGridSizer(0, 2, 0, 0) n_cams = options.GetOption("Webcams") self.WebcamsList = ['Webcam %s' % (int(w) + 1) for w in range(n_cams)] rb1 = wx.RadioButton(self, -1, 'Camera', style=wx.RB_GROUP) source1 = wx.ComboBox(self, -1, size=(285, -1), choices=self.WebcamsList, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) self.Bind(wx.EVT_COMBOBOX, self.sourceCallback, source1) rb2 = wx.RadioButton(self, -1, 'File') source2 = FileBrowseButton(self, -1, labelText='', size=(300, -1), changeCallback=self.sourceCallback) rb3 = wx.RadioButton(self, -1, 'Folder') source3 = DirBrowseButton(self, style=wx.DD_DIR_MUST_EXIST, labelText='', size=(300, -1), changeCallback=self.sourceCallback) self.controls = [] self.controls.append((rb1, source1)) self.controls.append((rb2, source2)) self.controls.append((rb3, source3)) for radio, source in self.controls: grid2.Add(radio, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) grid2.Add(source, 0, wx.ALIGN_CENTRE | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 2) self.Bind(wx.EVT_RADIOBUTTON, self.onChangeSource, radio) source.Enable(False) self.controls[0][1].Enable(True) #grid2.Add(wx.StaticText(self, -1, "")) sbSizer_2.Add(grid2) lowerSizer.Add(sbSizer_2, 0, wx.EXPAND | wx.ALL, 5) #Static box3 (RIGHT) sb_3 = wx.StaticBox(self, -1, "Set Tracking Parameters") sbSizer_3 = wx.StaticBoxSizer(sb_3, wx.VERTICAL) sbSizer_31 = wx.BoxSizer(wx.HORIZONTAL) self.activateTracking = wx.CheckBox(self, -1, "Activate Tracking") self.activateTracking.SetValue(False) self.activateTracking.Bind(wx.EVT_CHECKBOX, self.onActivateTracking) self.isSDMonitor = wx.CheckBox(self, -1, "Sleep Deprivation Monitor") self.isSDMonitor.SetValue(False) self.isSDMonitor.Bind(wx.EVT_CHECKBOX, self.onSDMonitor) self.isSDMonitor.Enable(False) sbSizer_31.Add(self.activateTracking, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_31.Add(self.isSDMonitor, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) self.pickMaskBrowser = FileBrowseButton(self, -1, labelText='Mask File') #sbSizer_3.Add ( self.activateTracking , 0, wx.ALIGN_LEFT|wx.LEFT|wx.RIGHT|wx.TOP, 5 ) sbSizer_3.Add(sbSizer_31, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_3.Add(self.pickMaskBrowser, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP | wx.EXPAND, 5) #trackingTypeSizer = wx.Sizer(wx.HORIZONTAL) self.trackDistanceRadio = wx.RadioButton( self, -1, "Activity as distance traveled", style=wx.RB_GROUP) self.trackVirtualBM = wx.RadioButton( self, -1, "Activity as midline crossings count") self.trackPosition = wx.RadioButton(self, -1, "Only position of flies") sbSizer_3.Add(wx.StaticText(self, -1, "Calculate fly activity as..."), 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 5) sbSizer_3.Add(self.trackDistanceRadio, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 2) sbSizer_3.Add(self.trackVirtualBM, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 2) sbSizer_3.Add(self.trackPosition, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, 2) lowerSizer.Add(sbSizer_3, -1, wx.EXPAND | wx.ALL, 5) self.SetSizer(lowerSizer) self.Bind(EVT_THUMBNAIL_CLICKED, self.onThumbnailClicked)
def __init__(self, parent): self.panel = wx.Panel.__init__(self, parent) self.fsPanel = previewPanel(self, size=options.GetOption("Resolution"), showtime=True) # %%%%%%%%%%%%%%%%%% sizer_Left: Monitor Display # Monitor Selection on top # Give title to the monitor selection combobox title_1 = wx.StaticText(self, wx.ID_ANY, 'Select Monitor') # create select monitor combobox on top of left column MonitorList = [ 'Monitor %s' % (int(m) + 1) for m in range(options.GetOption("Monitors")) ] # not reflecting number of monitors in configuration thumbnailNumber = wx.ComboBox(self, wx.ID_ANY, choices=MonitorList, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) self.Bind(wx.EVT_COMBOBOX, self.onChangeMonitor, thumbnailNumber) # sizer for left side, top row control buttons sizer_top_Left = wx.BoxSizer(wx.HORIZONTAL) sizer_top_Left.Add(title_1, 0, wx.ALL, 5) # menu title sizer_top_Left.Add(thumbnailNumber, 0, wx.ALL, 5) # menu # %% Movie Display on bottom videoWarper = wx.StaticBox(self, label='Movie Label', size=(x / 2, y * 2 / 3)) videoBoxSizer = wx.StaticBoxSizer(videoWarper, wx.VERTICAL) videoFrame = wx.Panel(self, wx.ID_ANY, size=(640, 480)) # cap = cv2.VideoCapture('fly_movie.avi') # not working on thinkpad computer # showCap = ShowCapture(videoFrame, cap) # not working on thinkpad computer videoBoxSizer.Add(videoFrame, 0) # Sizer for left side of display sizer_Left = wx.BoxSizer(wx.VERTICAL) sizer_Left.Add(sizer_top_Left, 0, wx.ALL, 5) # monitor combobox sizer_Left.Add(videoBoxSizer, 0, wx.ALL, 5) # movie # %%%%%%%%%%%%%%%%%% sizer_Right: Mask Editing # Section Title mask_editing = wx.StaticText(self, wx.ID_ANY, 'Mask Editing') # top row is single item, no sizer needed # # %% Clear Buttons btnClearAll = wx.Button(self, wx.ID_ANY, label="Clear All") # self.Bind(wx.EVT_BUTTON, self.fsPanel.ClearAll, self.btnClearAll) # btnClearSelected = wx.Button(self, wx.ID_ANY, label="Clear Selected") # self.Bind(wx.EVT_BUTTON, self.fsPanel.ClearLast, self.btnClearSelected) # # sizer for clear buttons on right side of display sizer_ClrBtns_Right = wx.BoxSizer(wx.HORIZONTAL) sizer_ClrBtns_Right.Add(btnClearSelected, 0, wx.ALL, 5) # clear selected sizer_ClrBtns_Right.Add(btnClearAll, 0, wx.ALL, 5) # clear all # %% AutoFill Value AFValue = wx.TextCtrl(self, -1, "32") # make this variable? btnAutoFill = wx.Button(self, wx.ID_ANY, label="Auto Fill") # self.Bind(wx.EVT_BUTTON, self.onAutoMask, self.btnAutoFill) # self.btnAutoFill.Enable(False) # sizer for AutoFill controls sizer_Autofill_Right = wx.BoxSizer(wx.HORIZONTAL) sizer_Autofill_Right.Add(btnAutoFill, 0, wx.ALL, 5) # Autofill sizer_Autofill_Right.Add(AFValue, 0, wx.ALL, 5) # AF Value # %% Right Side, Mask selection controls # Mask Title Mask_File_Title = wx.StaticText(self, wx.ID_ANY, "Curent Mask") self.currentMaskTXT = wx.TextCtrl(self, wx.ID_ANY, value='No Mask Selected', size=(x / 4, 20)) # style=wx.TE_READONLY) # get the current mask text for this # sizer for current mask sizer_currmsk_Right = wx.BoxSizer(wx.HORIZONTAL) # button section sizer_currmsk_Right.Add(Mask_File_Title, 0, wx.ALL, 5) # title sizer_currmsk_Right.Add(self.currentMaskTXT, 0, wx.ALL, 5) # title # %% # Mask Buttons btnLoad = wx.Button(self, wx.ID_ANY, label="Load Mask") self.Bind(wx.EVT_BUTTON, self.onLoadMask, btnLoad) btnSave = wx.Button(self, wx.ID_ANY, label="Save Mask") self.Bind(wx.EVT_BUTTON, self.onSaveMask, btnSave) btnSaveApply = wx.Button(self, wx.ID_ANY, label="Save + Apply") # self.Bind(wx.EVT_BUTTON, self.onSaveApply, self.btnSaveApply) # sizer for mask buttons sizer_maskIO_Right = wx.BoxSizer(wx.HORIZONTAL) # button section sizer_maskIO_Right.Add(btnLoad, 0, wx.ALL, 5) # load mask btn sizer_maskIO_Right.Add(btnSave, 0, wx.ALL, 5) # Save mask btn sizer_maskIO_Right.Add(btnSaveApply, 0, wx.ALL, 5) # Apply mask btn # %% Mouse Instructions # Section Title Controls_Title = wx.StaticText(self, wx.ID_ANY, "Mouse Controls") # titleFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD) instr = [ (' Left mouse button - single click outside ROI'), (' Start dragging ROI. ROI will be a perfect rectangle'), (' Left mouse button - single click inside ROI'), (' Select ROI. ROI turns red.'), (' Left mouse button - double click'), (' Select corner of ROI. Will close ROI after fourth selection' ), (' Middle mouse button - single click'), (' Add currently selected ROI. ROI turns white.'), (' Right mouse button - click'), (' Remove selected currently selected ROI'), (' Auto Fill'), (' Will fill 32 ROIS (16x2) to fit under the last two'), (' selected points. To use select first upper left corner,' ), (' then the lower right corner, then use "Auto Fill".') ] # # sizer for instructions sizer_instr_Right = wx.BoxSizer(wx.VERTICAL) # Help Section sizer_instr_Right.Add(Controls_Title, 0, wx.ALL, 5) # title for txtline in instr: instr_line = wx.StaticText(self, wx.ID_ANY, txtline) #; t.SetFont(titleFont) sizer_instr_Right.Add(instr_line, 0, wx.ALL, 1) # next instrctn # %% sizer for right side of display sizer_Right = wx.BoxSizer(wx.VERTICAL) sizer_Right.Add(mask_editing, 0, wx.ALL, 5) # section title sizer_Right.Add(sizer_ClrBtns_Right, 0, wx.ALL, 5) # Mask Buttons sizer_Right.Add(sizer_currmsk_Right, 0, wx.ALL, 5) # Mask Selection sizer_Right.Add(sizer_maskIO_Right, 0, wx.ALL, 5) # Mask Selection sizer_Right.Add(sizer_Autofill_Right, 0, wx.ALL, 5) # AutoFill sizer_Right.Add(sizer_instr_Right, 0, wx.ALL, 5) # Mouse Instruction # %% Full Panel sizer_All = wx.BoxSizer(wx.HORIZONTAL) # put everything together sizer_All.Add(sizer_Left, 0, wx.ALL, 5) sizer_All.Add(sizer_Right, 0, wx.ALL, 5) self.SetSizer(sizer_All) # displays the grid
def __set_properties(self): # begin wxGlade: mainFrame.__set_properties self.SetTitle("pySoloVideo") x, y = options.GetOption("Resolution") self.SetSize((x * 1.8, y * 1.4))
def drawPanel(self): """ """ ################################################### for child in self.GetChildren(): child.Destroy() mon_num = options.GetOption("Monitors") num_cams = options.GetOption("Webcams") monitorsData = options.getMonitorsData() WebcamsList = [ 'Camera %02d' % (int(w) +1) for w in range( num_cams ) ] colLabels = ['Status', 'Monitor', 'Source', 'Mask', 'Output', 'Track type', 'Track', 'uptime', 'preview'] tracktypes = ['DISTANCE','VBS','XY_COORDS'] mainSizer = wx.BoxSizer(wx.VERTICAL) gridSizer = wx.FlexGridSizer (cols=len(colLabels), vgap=5, hgap=5) #wx.BoxSizer(wx.VERTICAL) #FIRST ROW for key in colLabels: text = wx.StaticText(self, -1, key ) text.SetFont( wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD) ) gridSizer.Add(text, 0, wx.ALL|wx.ALIGN_CENTER, 5) self.status = [] self.recordBTNS = [] self.uptimeTXT = [] #LOOP THROUGH for mn in range(1, mon_num+1): if not options.HasMonitor(mn): options.SetMonitor(mn) #If monitor does not exist in options we create it md = options.GetMonitor(mn) try: _, source = os.path.split( md['source'] ) except: source = 'Camera %02d' % ( md['source'] ) _, mf = os.path.split(md['mask_file']) df = 'Monitor%02d.txt' % (mn) #ICON self.status.append( wx.StaticBitmap(self, -1, wx.EmptyBitmap(16,16)) ) gridSizer.Add(self.status[-1], 0, wx.ALL|wx.ALIGN_CENTER, 5) self.changeIcon(mn) #TEXT gridSizer.Add(wx.StaticText(self, -1, "Monitor %s" % mn ), 0, wx.ALL|wx.ALIGN_CENTER, 5) #INPUT SOURCE gridSizer.Add(comboFileBrowser(self, wx.ID_ANY, size=(-1,-1), dialogTitle = "Choose an Input video file", startDirectory = options.GetOption("Data_Folder"), value = source, choices=WebcamsList, fileMask = "Video File (*.*)|*.*", browsevalue="Browse for video...", changeCallback = partial(self.onChangeDropDown, [mn, "source"])), 0, wx.ALL|wx.ALIGN_CENTER, 5 ) #MASK FILE gridSizer.Add(comboFileBrowser(self, wx.ID_ANY, size=(-1,-1), dialogTitle = "Choose a Mask file", startDirectory = options.GetOption("Mask_Folder"), value = mf, fileMask = "pySolo mask file (*.msk)|*.msk", browsevalue="Browse for mask...", changeCallback = partial(self.onChangeDropDown, [mn, "mask_file"])), 0, wx.ALL|wx.ALIGN_CENTER, 5 ) #OUTPUT FILE gridSizer.Add(comboFileBrowser(self, wx.ID_ANY, size=(-1,-1), dialogTitle = "Choose the output file", startDirectory = options.GetOption("Data_Folder"), value = md['outputfile'], fileMask = "Output File (*.txt)|*.txt", browsevalue="Browse for output...", changeCallback = partial(self.onChangeDropDown, [mn, "outputfile"])), 0, wx.ALL|wx.ALIGN_CENTER, 5 ) #TRACKTYPE ttcb = wx.ComboBox(self, -1, size=(-1,-1), value=md['track_type'], choices=tracktypes, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) ttcb.Bind (wx.EVT_COMBOBOX, partial(self.onChangeDropDown, [mn, "track_type"])) gridSizer.Add(ttcb , 0, wx.ALL|wx.ALIGN_CENTER, 5) #RECORD BUTTON self.recordBTNS.append ( wx.ToggleButton(self, wx.ID_ANY, 'Start') ) self.recordBTNS[-1].Bind (wx.EVT_TOGGLEBUTTON, partial( self.onToggleRecording, mn)) gridSizer.Add(self.recordBTNS[-1], 0, wx.ALL|wx.ALIGN_CENTER, 5) #UPTIME self.uptimeTXT.append(wx.TextCtrl(self, value="00:00:00", size=(140,-1))) gridSizer.Add(self.uptimeTXT[-1], 0, wx.ALL|wx.ALIGN_CENTER, 5) #VIEW BUTTON vb = wx.Button(self, wx.ID_ANY, 'View') vb.Bind(wx.EVT_BUTTON, partial( self.onViewMonitor, mn)) gridSizer.Add(vb, 0, wx.ALL|wx.ALIGN_CENTER, 5) btnSizer = wx.BoxSizer(wx.HORIZONTAL) conf_btnSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, 'Configuration'), wx.HORIZONTAL) acq_btnSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, 'Acquisition'), wx.HORIZONTAL) self.saveOptionsBtn = wx.Button(self, wx.ID_ANY, 'Save') self.saveOptionsBtn.Enable(False) self.Bind(wx.EVT_BUTTON, self.onSave, self.saveOptionsBtn) conf_btnSizer.Add (self.saveOptionsBtn, 0, wx.ALL, 5) self.startBtn = wx.Button(self, wx.ID_ANY, 'Start All') self.stopBtn = wx.Button(self, wx.ID_ANY, 'Stop All') self.startBtn.Enable(True) self.stopBtn.Enable(False) self.Bind(wx.EVT_BUTTON, self.onStopAll, self.stopBtn) self.Bind(wx.EVT_BUTTON, self.onStartAll, self.startBtn) acq_btnSizer.Add (self.startBtn, 0, wx.ALL, 5) acq_btnSizer.Add (self.stopBtn, 0, wx.ALL, 5) btnSizer.Add(conf_btnSizer, 0, wx.ALL, 5) btnSizer.Add(acq_btnSizer, 0, wx.ALL, 5) #mainSizer.Add(self.FBconfig, 0, wx.EXPAND|wx.ALL, 5) mainSizer.Add(gridSizer, 1, wx.EXPAND, 0) mainSizer.Add(btnSizer, 0, wx.ALL, 5) mainSizer.Layout() self.SetSizer(mainSizer) self.Refresh()
def drawSingleMonitor(self, mn, WebcamsList, tracktypes): if not options.HasMonitor(mn): options.SetMonitor(mn) md = options.GetMonitor(mn) try: _, source = os.path.split(md['source']) except: source = 'Camera %02d' % (md['source']) _, mf = os.path.split(md['mask_file']) df = 'Monitor%02d.txt' % (mn) #ICON self.status.append(wx.StaticBitmap(self, -1, wx.EmptyBitmap(16, 16))) self.gridSizer.Add(self.status[-1], 0, wx.ALL | wx.ALIGN_CENTER, 5) self.changeIcon(mn) #TEXT self.gridSizer.Add( # Monitor number label wx.StaticText(self, -1, "Monitor %s" % mn), 0, wx.ALL | wx.ALIGN_CENTER, 5) self.gridSizer.Add( # Choose video input comboFileBrowser(self, wx.ID_ANY, size=(-1, -1), dialogTitle="Choose an Input video file", startDirectory=options.GetOption("Data_Folder"), value=source, choices=WebcamsList, fileMask="Video File (*.*)|*.*", browsevalue="Browse for video...", changeCallback=partial(self.onChangeDropDown, [mn, "source"])), 0, wx.ALL | wx.ALIGN_CENTER, 5) self.gridSizer.Add( # Choose mask file comboFileBrowser(self, wx.ID_ANY, size=(-1, -1), dialogTitle="Choose a Mask file", startDirectory=options.GetOption("Mask_Folder"), value=mf, fileMask="pySolo mask file (*.msk)|*.msk", browsevalue="Browse for mask...", changeCallback=partial(self.onChangeDropDown, [mn, "mask_file"])), 0, wx.ALL | wx.ALIGN_CENTER, 5) self.gridSizer.Add( # Choose output file comboFileBrowser(self, wx.ID_ANY, size=(-1, -1), dialogTitle="Choose the output file", startDirectory=options.GetOption("Data_Folder"), value=md['outputfile'], fileMask="Output File (*.txt)|*.txt", browsevalue="Browse for output...", changeCallback=partial(self.onChangeDropDown, [mn, "outputfile"])), 0, wx.ALL | wx.ALIGN_CENTER, 5) #TRACKTYPE ttcb = wx.ComboBox(self, -1, size=(-1, -1), value=md['track_type'], choices=tracktypes, style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.CB_SORT) ttcb.Bind(wx.EVT_COMBOBOX, partial(self.onChangeDropDown, [mn, "track_type"])) self.gridSizer.Add(ttcb, 0, wx.ALL | wx.ALIGN_CENTER, 5) #RECORD BUTTON self.recordBTNS.append(wx.ToggleButton(self, wx.ID_ANY, 'Start')) self.recordBTNS[-1].Bind(wx.EVT_TOGGLEBUTTON, partial(self.onToggleRecording, mn)) self.gridSizer.Add(self.recordBTNS[-1], 0, wx.ALL | wx.ALIGN_CENTER, 5) #UPTIME self.uptimeTXT.append( wx.TextCtrl(self, value="00:00:00", size=(140, -1))) self.gridSizer.Add(self.uptimeTXT[-1], 0, wx.ALL | wx.ALIGN_CENTER, 5) #VIEW BUTTON vb = wx.Button(self, wx.ID_ANY, 'View') vb.Bind(wx.EVT_BUTTON, partial(self.onViewMonitor, mn)) self.gridSizer.Add(vb, 0, wx.ALL | wx.ALIGN_CENTER, 5)
# %% """ refreshes screens """ def updateUI(self): self.panelOne.onRefresh() self.panelTwo.onRefresh() self.Layout() # %% """ refreshes screens after configuration change """ def OnPageChanging(self, event): # self.panelOne.StopPlaying() # old, unnecessary code? self.panelTwo.StopPlaying() # %% """ Main Program """ x, y = options.GetOption("Resolution") # screen resolution global variables. if __name__ == "__main__": app = wx.App(False) # Create a new GUI, # False => don't redirect stdout/stderr to a window. frame_1 = mainFrame(None, -1, "") # create the GUI window frame_1.Show() app.SetTopWindow(frame_1) app.MainLoop() # begin interaction with user print('done') # temporary debug print