def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # Give the root frame a minimum size, and make it flexible in the # middle column (like other frames in this interface) self.root.columnconfigure(0, weight=1, minsize=200) self.root.columnconfigure(1, weight=1) # Row counter i = 1 # Create a button that will invoke the 'plotSpec' method and plot the # spectrum with Biggles. Provide an on-line help text for this button. replotbutton = Button(self.root, text='Replot last spectrum', command=self.plotSpec) replotbutton.grid(row=i, column=0, columnspan=2, sticky=E + W) replotbuttonPopup = popUp.popUp( self.root, replotbutton, title='Replot last spectrum', text="""Replot the last reduced spectrum. You will be prompted for a file if you have not reduced any spectra yet. """) # Next row i = i + 1 # Create a radiobutton for the option to plot spectra with the simple # 'Biggles' plotting package. Provide an on-line help text for this option. biggButton = Radiobutton(self.root, width=25, text='Plot with Biggles', variable=self.usebiggles, value=1, indicatoron=1, pady=4) biggButton.grid(row=i, column=0, sticky=E + W) biggButtonPopup = popUp.popUp( self.root, biggButton, title='Biggles', text="""Biggles is a simple plotting package, producing non-interactive plots. Biggles' plots appear in popup windows that can be closed by clicking on them. """) # Create another radiobutton for the option to plot spectra with the # 'splot'-function of IRAF. The call to this function will go through # PyRAF. Provide an on-line help text for this option. irafButton = Radiobutton(self.root, width=25, text='Plot with IRAF', variable=self.usebiggles, value=0, indicatoron=1, pady=4) irafButton.grid(row=i, column=1, sticky=E + W) irafButtonPopup = popUp.popUp( self.root, irafButton, title='IRAF plots', text="""IRAF plots are produced with the 'splot' routine from the echelle reduction package. The plots appear in a popup window that can be closed by pressing 'q' with the mouse in the window. There are a large number of simple spectrum analysis tools available (press '?' for help). """) # Next row i = i + 1 # Create a configuration button for the starting wavelength wavebutton1 = configFrame.window(self.root, optionlist=['plot_startwave'], embed=True, width=20) wavebutton1.grid(row=i, column=0, sticky=E + W) # Idem for the ending wavelength wavebutton2 = configFrame.window(self.root, optionlist=['plot_endwave'], embed=True, width=20) wavebutton2.grid(row=i, column=1, sticky=E + W) # Next row i = i + 1 # And a configuration button for plotting individual orders (not very common) orderbutton = configFrame.window(self.root, optionlist=['plot_defaultorder'], embed=True, width=20) orderbutton.grid(row=i, column=0, sticky=E + W) Label(self.root, anchor=W, text='(if no wavelengths available)').grid(row=i, column=1, stick=E + W) # Next row i = i + 1 # Create a button that will invoke the 'plotSpec' method and plot the # spectrum with Biggles. Provide an on-line help text for this button. plotbutton = Button(self.root, text='Plot other spectrum', command=lambda: self.plotSpec(plotother=True)) plotbutton.grid(row=i, column=0, columnspan=2, sticky=E + W) plotbuttonPopup = popUp.popUp( self.root, plotbutton, title='Plot other spectrum', text="""Plot a reduced spectrum using Biggles or IRAF. You will be prompted for a file if 'Use default filename' is not selected (or no valid filename is listed there). """) # Next row i = i + 1 # NOT YET IMPLEMENTED. DO WE REALLY WANT TO PROVIDE HARDCOPIES, # OR IS THAT NOT THE TASK OF QUICKLOOK REDUCTION SOFTWARE? # # hardcopyButton = Button(self.root, text='Send last plot to printer', # command=lambda: self.printSpec) # hardcopyButton.grid(row=i, column=1, sticky=E+W) # harccopyButtonPopup = popUp.popUp(self.root, hardcopyButton, title='Biggles', # text="""Send the latest Biggles plot to the printer # """) # # i = i + 1 # Finally, display the entire frame (that is, the 'root' frame) self.root.grid(sticky=E + W)
def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # Give the root frame a minimum size, and make it flexible in the # middle column (like other frames in this interface) self.root.columnconfigure(0, weight=1, minsize=200) self.root.columnconfigure(1, weight=1) # Row counter i = 1 # Create a button that will invoke the 'plotSpec' method and plot the # spectrum with Biggles. Provide an on-line help text for this button. replotbutton = Button(self.root, text='Replot last spectrum', command=self.plotSpec) replotbutton.grid(row=i, column=0, columnspan=2, sticky=E+W) replotbuttonPopup = popUp.popUp(self.root, replotbutton, title='Replot last spectrum', text="""Replot the last reduced spectrum. You will be prompted for a file if you have not reduced any spectra yet. """) # Next row i = i + 1 # Create a radiobutton for the option to plot spectra with the simple # 'Biggles' plotting package. Provide an on-line help text for this option. biggButton = Radiobutton(self.root, width=25, text='Plot with Biggles', variable=self.usebiggles, value=1, indicatoron=1, pady=4) biggButton.grid(row=i, column=0, sticky=E+W) biggButtonPopup = popUp.popUp(self.root, biggButton, title='Biggles', text="""Biggles is a simple plotting package, producing non-interactive plots. Biggles' plots appear in popup windows that can be closed by clicking on them. """) # Create another radiobutton for the option to plot spectra with the # 'splot'-function of IRAF. The call to this function will go through # PyRAF. Provide an on-line help text for this option. irafButton = Radiobutton(self.root, width=25, text='Plot with IRAF', variable=self.usebiggles, value=0, indicatoron=1, pady=4) irafButton.grid(row=i, column=1, sticky=E+W) irafButtonPopup = popUp.popUp(self.root, irafButton, title='IRAF plots', text="""IRAF plots are produced with the 'splot' routine from the echelle reduction package. The plots appear in a popup window that can be closed by pressing 'q' with the mouse in the window. There are a large number of simple spectrum analysis tools available (press '?' for help). """) # Next row i = i + 1 # Create a configuration button for the starting wavelength wavebutton1 = configFrame.window(self.root, optionlist=['plot_startwave'], embed=True, width=20) wavebutton1.grid(row=i, column=0, sticky=E+W) # Idem for the ending wavelength wavebutton2 = configFrame.window(self.root, optionlist=['plot_endwave'], embed=True, width=20) wavebutton2.grid(row=i, column=1, sticky=E+W) # Next row i = i + 1 # And a configuration button for plotting individual orders (not very common) orderbutton = configFrame.window(self.root, optionlist=['plot_defaultorder'], embed=True, width=20) orderbutton.grid(row=i, column=0, sticky=E+W) Label(self.root, anchor=W, text='(if no wavelengths available)').grid(row=i, column=1, stick=E+W) # Next row i = i + 1 # Create a button that will invoke the 'plotSpec' method and plot the # spectrum with Biggles. Provide an on-line help text for this button. plotbutton = Button(self.root, text='Plot other spectrum', command=lambda:self.plotSpec(plotother=True) ) plotbutton.grid(row=i, column=0, columnspan=2, sticky=E+W) plotbuttonPopup = popUp.popUp(self.root, plotbutton, title='Plot other spectrum', text="""Plot a reduced spectrum using Biggles or IRAF. You will be prompted for a file if 'Use default filename' is not selected (or no valid filename is listed there). """) # Next row i = i + 1 # NOT YET IMPLEMENTED. DO WE REALLY WANT TO PROVIDE HARDCOPIES, # OR IS THAT NOT THE TASK OF QUICKLOOK REDUCTION SOFTWARE? # # hardcopyButton = Button(self.root, text='Send last plot to printer', # command=lambda: self.printSpec) # hardcopyButton.grid(row=i, column=1, sticky=E+W) # harccopyButtonPopup = popUp.popUp(self.root, hardcopyButton, title='Biggles', # text="""Send the latest Biggles plot to the printer # """) # # i = i + 1 # Finally, display the entire frame (that is, the 'root' frame) self.root.grid(sticky=E+W)
def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # Make also the root frame flexible in width self.root.columnconfigure(0, weight=1) # Row counter i = 0 # Display a 'window' instance of the 'configFrame' class for a number # of input options. optionlist = ('inpath', 'filename_filter', 'biaslist', 'flatlist', 'orderdef', 'wavedef', 'interlacedorderdef', 'interlacedwavedef') configFrame.window(self, optionlist=optionlist, title='Input options', embed=1).grid(row=i, stick=E+W) # Next row i = i + 1 # Do the same for the output options optionlist = ('refpath', 'masterbias', 'masterflat', 'masternormflat', 'blazeshape', 'masterorderdef', 'waveref', 'masterwaveref', 'masterinterlacedorderdef', 'interlacedwaveref') configFrame.window(self, optionlist=optionlist, title='Output options', embed=1).grid(row=i, stick=E+W) # Next row i = i + 1 # Display a header label label = Label(self, text='Calculate calibration frames :') label.grid(row=i, columnspan=2, sticky=E+W) # Next row i = i + 1 # Create a list containing each task mentioned in 'tasknames' self.tasklist = [ getattr(tasks, taskname) for taskname in tasknames ] # For each task, create a 'taskBar' object, which consists of (1) a # button to execute the task and (2) a status line. for task in self.tasklist: # Store in self.taskbars the taskBar instance that correspond to this # task and attach the 'runTask' method to the button. self.taskbars[task.name] = taskBar.taskBar(self.root, task) self.taskbars[task.name].button.config(command = lambda t = task: self.runTask(t)) self.taskbars[task.name].grid(sticky=E+W) # Next row i = i + 1 # At the bottom, display an 'OK' button that will close (hide) the window self.okbutton = Button(self.root, text='OK', command=self.hide) self.okbutton.grid(row=i, columnspan=2, sticky=E+W) # Display the contents of the root frame self.root.grid(sticky=E+W)
def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # Give the root frame a minimum size, and make it flexible in the # middle column self.root.columnconfigure(0, weight=0, minsize=200) self.root.columnconfigure(1, weight=1) self.root.columnconfigure(2, weight=1) # Row counter i = 1 # Label for first row Label(self.root, anchor=W, text='Number of files in queue', width=25).grid(row=i, column=0, sticky=E + W) # Text entry for first row, containing the number of unprocessed files nqueue = Entry(self.root, textvariable=self.queuesize, state=DISABLED) # Try to make the text color of this item black. # For compatibility purposes with Python versions < 2.3. try: nqueue.config(disabledforeground='black') except TclError: pass # And display this label nqueue.grid(row=i, column=1, sticky=E + W) # Button to modify the selection of unprocessed files queueButton = Button(self.root, text='Edit queue', width=25) queueButton.config(command=self.editNewFiles) queueButton.grid(row=i, column=2, sticky=E + W) # And attach popup-help to this button. queuePopup = popUp.popUp( self.root, queueButton, title='Edit files in queue', text="""Select or deselect files that are pending to be processed. Selecting files that are already processed will cause them to be reprocessed. """) # Next row i = i + 1 # Label for second row Label(self.root, anchor=W, text='Number of processed files', width=25).grid(row=i, column=0, sticky=E + W) # Text entry for second row, containing the number of processed files nproc = Entry(self.root, textvariable=self.reducedsize, state=DISABLED) # Try to make the text color of this item black. # For compatibility purposes with Python versions < 2.3. try: nproc.config(disabledforeground='black') except TclError: pass # And display this label nproc.grid(row=i, column=1, sticky=E + W) # Button to modify the selection of reduced files listButton = Button(self.root, text='Edit list of processed files', width=25) listButton.config(command=self.editReducedFiles) listButton.grid(row=i, column=2, sticky=E + W) # And attach popup-help to this button. listPopup = popUp.popUp( self.root, listButton, title='Edit list of processed files', text="""View and change the list of processed files. Deselecting processed files will NOT cause them to be reprocessed. """) # Next row i = i + 1 filterEntry = configFrame.window(self.root, optionlist=['filename_filter'], embed=True, width=100) filterEntry.grid(row=i, column=0, columnspan=2, sticky=E + W) # Label for third row #Label(self.root, width=25, anchor=W, text='Filename filter').grid(row=i, # column=0, sticky=E+W) # Text entry for third row, containing the filter pattern used when # automatically selecting items for the unprocessed list. #filterEntry = Entry(self.root, textvariable=self.filterpattern) #filterEntry.grid(row=i, column=1, sticky=E+W) # Attach popup-help to this entry. filterPopup = popUp.popUp( self.root, filterEntry, title='Filename filter', text="""When AutoCheck is running, files that match this filter will automatically be appended to the queue of files waiting to be processed. """) # Checkbutton to enable/disable automatic checking for the arrival of # unprocessed files that match the pattern in the entry above autoButton = Checkbutton(self.root, width=25, text='Autocheck for new files', variable=self.autocheck) autoButton.grid(row=i, column=2, sticky=E + W) # Associate with this checkbox the method that starts automatich checking autoButton.config(command=self.autoCheckFiles) # Attach popup-help to this entry. autoPopup = popUp.popUp( self.root, autoButton, title='Filename filter', text="""Turning this option on will start periodic checking of the arrival of new files in the input directory. If a newly created file matches the filename filter, it will be appended to the queue of files waiting to be processed. Checking this box will not automatically start the data processing. Use the 'START processing' button for that. """) # Finally, display the entire frame (that is, the 'root' frame) self.root.grid(sticky=E + W)
def __init__(self, parent, hasscrollbar=False): ############################################### # First prepare and create this frame # ############################################### self.hasscrollbar = hasscrollbar # GUIupdater' contains a Queue.Queue object into # which calls for updating the GUI may be placed (useful when running # as a thread). These variables are global in this class self.GUIupdater = Queue.Queue() # Was an additional scrollbar requested? if self.hasscrollbar: # Add a scrollbar vscrollbar = AutoScrollbar(parent) vscrollbar.grid(row=0, column=1, sticky=N + S) # Create a Canvas object that can contain the whole frame self.canvas = Canvas(parent, yscrollcommand=vscrollbar.set) self.canvas.columnconfigure(0, weight=1) self.canvas.rowconfigure(0, weight=1) # Attach the method to position the canvas to the scrollbar vscrollbar.config(command=self.canvas.yview) # Inialize as if this were an instance of the Frame class Frame.__init__(self, self.canvas) else: # Inialize as if this were an instance of the Frame class Frame.__init__(self, parent) # And make 'self' frame flexible in width and heigth self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) # Build this frame self.makeFrame() ############################################### # Now prepare and create all the child frames # ############################################### # These are 'all' the editable options that should appear in the main configuration frame alloptions = [ 'inpath', 'outpath', 'filename_filter', 'biaslist', 'flatlist', 'orderdef', 'wavedef', 'interlacedorderdef', 'interlacedwavedef', 'refpath', 'pixelmask', 'masterbias', 'masterflat', 'masternormflat', 'blazeshape', 'masterorderdef', 'waveref', 'masterwaveref', 'masterinterlacedorderdef', 'interlacedwaveref', 'fitsheaders', 'mef_dataext', 'frameorientation', 'config_dir', 'iraf_taskconfig_dir', 'x_start', 'x_end', 'y_start', 'y_end', ] # Create the main configuration frame self.mainConfig = configFrame.window( self, optionlist=alloptions, title='FIEStool - Configure all settings') # Create the frame for calculating calibration (reference) data self.CF = calibFrame.window( self, self.GUIupdater, title='FIEStool - Calculate reference data') # Create the autoLoader frame self.AL = autoLoader.window(self) # Attach a menubar to this frame. This can only be done after the other frames # have been created, because the menubar makes calls to these frames self.MB = MenuBar(self) parent.config(menu=self.MB) # Start automatic updating of this frame self.updateGUI() if self.hasscrollbar: # Store it in a canvas object (to allow scrolling) self.canvas.create_window(0, 0, anchor=NW, window=self)
def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # The root frame should be flexible in width self.root.columnconfigure(0, weight=1) # Row counter i = 0 # Add title Label(self.root, text='FIES automated data reduction interface').grid( row=i, sticky=E + W) # Next row i = i + 1 # Insert an embedded configuration window so one can easily see and change th # location of the input and output frames self.CF = configFrame.window(self.root, optionlist=['inpath', 'outpath'], embed=1, width=200) # Display this embedded frame self.CF.grid(row=i, sticky=E + W) # Next row i = i + 1 # Insert the autoQueue frame, controlling the queue of files to be processed self.AQ = autoQueue.window(self.root) # Display this embedded frame self.AQ.grid(row=i, sticky=E + W) # Next row i = i + 1 # Create and display the button to start processing self.startbutton = Button(self.root, text='START processing', command=self.startProcess) self.startbutton.grid(sticky=E + W) # Save the default fg and bg colors self.startbutton.defaultbgcolor = self.startbutton.cget('bg') self.startbutton.defaultactivecolor = self.startbutton.cget( 'activebackground') # Add a popup to this button startPopup = popUp.popUp( self.root, self.startbutton, title='Start/Stop processing', text="""Start (or stop) the processing of files in the queue. Only one file at a time will be processed. Stopping the queue processing will not interrupt any active process. """) # Next row i = i + 1 # Create and display the window containing the pipeline tasks self.PL = pipeFrame.window(self.root, self.GUIupdater) self.PL.grid(row=i, sticky=E + W) # Next row i = i + 1 # Create and display the window controlling all plotting self.PF = plotFrame.window(self.root) self.PF.grid(row=i, sticky=E + W) # Next row i = i + 1 # Create and display the logging window self.ML = messageLog.window(self.root) self.ML.grid(row=i, sticky=N + E + S + W) self.root.rowconfigure(i, weight=1) # Next row i = i + 1 # Now display the entire frame self.root.grid(sticky=N + E + S + W)
def __init__(self, parent, hasscrollbar=False): ############################################### # First prepare and create this frame # ############################################### self.hasscrollbar = hasscrollbar # GUIupdater' contains a Queue.Queue object into # which calls for updating the GUI may be placed (useful when running # as a thread). These variables are global in this class self.GUIupdater = Queue.Queue() # Was an additional scrollbar requested? if self.hasscrollbar: # Add a scrollbar vscrollbar = AutoScrollbar(parent) vscrollbar.grid(row=0, column=1, sticky=N+S) # Create a Canvas object that can contain the whole frame self.canvas = Canvas(parent, yscrollcommand=vscrollbar.set) self.canvas.columnconfigure(0, weight=1) self.canvas.rowconfigure(0, weight=1) # Attach the method to position the canvas to the scrollbar vscrollbar.config(command=self.canvas.yview) # Inialize as if this were an instance of the Frame class Frame.__init__(self, self.canvas) else: # Inialize as if this were an instance of the Frame class Frame.__init__(self, parent) # And make 'self' frame flexible in width and heigth self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) # Build this frame self.makeFrame() ############################################### # Now prepare and create all the child frames # ############################################### # These are 'all' the editable options that should appear in the main configuration frame alloptions = ['inpath', 'outpath', 'filename_filter', 'biaslist', 'flatlist', 'orderdef', 'wavedef', 'interlacedorderdef', 'interlacedwavedef', 'refpath', 'pixelmask', 'masterbias', 'masterflat', 'masternormflat', 'blazeshape', 'masterorderdef', 'waveref', 'masterwaveref', 'masterinterlacedorderdef', 'interlacedwaveref', 'fitsheaders', 'mef_dataext', 'frameorientation', 'config_dir', 'iraf_taskconfig_dir', 'x_start', 'x_end', 'y_start', 'y_end', ] # Create the main configuration frame self.mainConfig = configFrame.window(self, optionlist=alloptions, title='FIEStool - Configure all settings') # Create the frame for calculating calibration (reference) data self.CF = calibFrame.window(self, self.GUIupdater, title='FIEStool - Calculate reference data') # Create the autoLoader frame self.AL = autoLoader.window(self) # Attach a menubar to this frame. This can only be done after the other frames # have been created, because the menubar makes calls to these frames self.MB = MenuBar(self) parent.config(menu = self.MB) # Start automatic updating of this frame self.updateGUI() if self.hasscrollbar: # Store it in a canvas object (to allow scrolling) self.canvas.create_window(0,0, anchor=NW, window=self)
def makeFrame(self): "Construct the frame from scratch" # Put all data in a root frame that is embedded in the 'self' Frame object. # In this way, it is possible to destroy and rebuid the frame object, # without destroying the 'self' frame object. self.root = Frame(self) # The root frame should be flexible in width self.root.columnconfigure(0, weight=1) # Row counter i = 0 # Add title Label(self.root, text='FIES automated data reduction interface').grid(row=i, sticky=E+W) # Next row i = i + 1 # Insert an embedded configuration window so one can easily see and change th # location of the input and output frames self.CF = configFrame.window(self.root, optionlist=['inpath', 'outpath'], embed=1, width=200) # Display this embedded frame self.CF.grid(row=i, sticky=E+W) # Next row i = i + 1 # Insert the autoQueue frame, controlling the queue of files to be processed self.AQ = autoQueue.window(self.root) # Display this embedded frame self.AQ.grid(row=i, sticky=E+W) # Next row i = i + 1 # Create and display the button to start processing self.startbutton = Button(self.root, text='START processing', command=self.startProcess) self.startbutton.grid(sticky=E+W) # Save the default fg and bg colors self.startbutton.defaultbgcolor = self.startbutton.cget('bg') self.startbutton.defaultactivecolor = self.startbutton.cget('activebackground') # Add a popup to this button startPopup = popUp.popUp(self.root, self.startbutton, title='Start/Stop processing', text="""Start (or stop) the processing of files in the queue. Only one file at a time will be processed. Stopping the queue processing will not interrupt any active process. """) # Next row i = i + 1 # Create and display the window containing the pipeline tasks self.PL = pipeFrame.window(self.root, self.GUIupdater) self.PL.grid(row=i, sticky=E+W) # Next row i = i + 1 # Create and display the window controlling all plotting self.PF = plotFrame.window(self.root) self.PF.grid(row=i, sticky=E+W) # Next row i = i + 1 # Create and display the logging window self.ML = messageLog.window(self.root) self.ML.grid(row=i, sticky=N+E+S+W) self.root.rowconfigure(i, weight=1) # Next row i = i + 1 # Now display the entire frame self.root.grid(sticky=N+E+S+W)