Source code for lfd.gui.jobcreator.leftmidframe

import os
import threading
import queue
import time

from tkinter import *
from tkinter.ttk import *
from tkinter import filedialog, messagebox

import lfd.createjobs as cj
from lfd.gui.utils import utils
import lfd.results as results

[docs]class MidFrame(Frame): """Part of the LeftFrame of the GUI. Contains the drop-down menu that selects the runs that will be processed. Currently the option to select from results database are a bit wonky. Requires a parent Frame that has access to Job object so that the settings can propagate to it. """ def __init__(self, parent, row=1, col=0): Frame.__init__(self, parent) self.parent = parent self.grid(row=row, column=col) title = Label(self, text="Run(s) options", font=("Helvetica", 16), justify="center") title.grid(row=row, column=col, columnspan=2) # this is the same job from root, so that settings can be changed self.job = self.parent.job self.runs = None # the respath and uri will only be used if the source of runs are # results - otherwise mostly ignored. self.respath = "~/Desktop" self.uri = "sqlite:///" runsl = Label(self, text="Runs: ") runsl.grid(row=row+1, column=col, pady=5, sticky=W) self.tmpruns = StringVar(self) self.tmpruns.set("All") # the first All seems as the default "title" setting to tell users # what the dropdown menu is for, the second one is then registered as # an option that won't dissapear after selection. runsom = OptionMenu(self, self.tmpruns, "All", "All", "Single", "List", "Results", "Errors", command=self.selectRuns) runsom.grid(row=row+1, column=col+1, pady=5, sticky=W+E)
[docs] def selectRuns(self,selection): """Callback that will execute everytime the drop-down menu selection changes. For each of the option in the menu here we define an action that will triger the appropriate additional menus required to configure the job. * All - the runs are allowed to be undefined, createjobs package will read the runlistAll file in $PHOTO_REDUX env var location for runs * Single - a pop-up with an entry field is displayed where only 1 run id is permitted * List - a pop-up with a textbox is displayed where a list of runs is given as a comma separated string * Results - a pop-up window that lets user select the DB from which jobs will be created. """ if selection == "All": self.runs = None # we return early for this case to avoid spawning the toplevel return # otherwise we spawn another window which will hold the boxes where # user will fill in run or runs or pick the results DB top = Toplevel(self.parent) top.title(selection) top.geometry(utils.centerWindow(self.parent, 250,200)) if selection == "Single": a = Label(top, text="Input a single run:", justify="left") a.grid(row=0, column=0, pady=10, padx=10) tempruns = Entry(top) tempruns.grid(row=1, column=0, pady=10, padx=10) c = Button(top, text="Ok", command = lambda parent=top, runs=tempruns: self.runFromSingle(parent, runs) ) c.grid(row=2, column=0, pady=10, padx=10) elif selection == "List": a = Label(top, text="Input a list of runs.\n"+ \ "Separate each run with a coma.", justify="left") a.grid(row=0, column=0, pady=10, padx=5) tempruns = Text(top, height=4, width=30, pady=10, padx=10) tempruns.grid(row=1, column=0, pady=10, padx=10) b = Button(top, text="Ok", command=lambda parent=top, runs=tempruns: self.runsFromList(parent, runs)) b.grid(row=2, column=0, pady=10) elif selection == "Results": respathVar = StringVar() respathVar.set(self.respath) respathVar.trace("w", lambda a, b, c, path=respathVar: self.setResPath(a, b, c, path)) uriVar = StringVar() uriVar.set(self.uri) uriVar.trace("w", lambda a, b, c, path=uriVar: self.setUriPath(a, b, c, path)) a = Label(top, text="Is this the correct DB:", justify="left") a.grid(row=0, column=0, pady=10, padx=10, columnspan=2) b = Entry(top, textvariable=uriVar) b.grid(row=1, column=0, columnspan=2, pady=10, padx=10) c = Label(top, text="Is this the correct path:", justify="left") c.grid(row=2, column=0, pady=10, padx=10, columnspan=2) d = Entry(top, textvariable=respathVar) d.grid(row=3, column=0, columnspan=2, pady=10, padx=10) e = Button(top, text="Reselect DB file", command = lambda parent=top, updateVar=respathVar: self.getResultsDBPath(parent, updateVar)) e.grid(row=4, column=0, pady=10, padx=10) f = Button(top, text="Ok", command=lambda parent=top: self.readRes(parent)) f.grid(row=5, column=1)
[docs] def runFromSingle(self, parent, runs): """Callback function for the case when a 'Single' run source is chosen. Parameters ---------- parent - the parent window that contains the widget that registers this callback. This window will be destroyed at the end of this func. runs - an Entry or a Text widget from which the value will be read out as. """ # see selection=="Single" in selectRuns method (above) try: self.runs = [ int( runs.get() ) ] except ValueError: messagebox.showerror("Input Error", "You have inputed "+\ "runs in an incorrect format!") parent.destroy()
[docs] def setResPath(self, *tmp): """Callback 'observer' function used to track when the contents of an Entry changes. Specifically, tracks when the text value of an Entry used to select path to results database has changed. Updates the stored path to the results. Expects the arguments corresponding to the invocation of trace method of a StringVar. """ # see selection=="Results" in selectRuns method (variable respathVar) self.respath = tmp[-1].get()
[docs] def setUriPath(self, *tmp): """Callback 'observer' function used to track when the contents of an Entry changes. Specifically, tracks when the text value of an Entry used to select URI path to results database has changed. Updates the stored URI path to the results. Expects the arguments corresponding to the invocation of trace method of a StringVar. """ # see selection=="Results" in selectRuns method (variable uriVar) self.uri = tmp[-1].get()
[docs] def readRes(self, parent): """Callback that connects to the database given by the URI and path provided by the user and selects all existing Frames in that database. Selected frames are propagated to the runs attribute of the job object inherited from root. Expects to receive the parent window containing the binding object. The parent window is destroyed once all results are read in. """ # see selection=="Results" in selectRuns method (OK button) import lfd.results as results results.connect2db(self.uri+self.respath) self.runs = results.Frame.query().all() parent.destroy()
[docs] def runsFromList(self, parent, runs): """Callback function to convert a coma separated string of runs into a list of integers. Propagates the list to the job object inherited from root. Expects to receive the parent window containing the binding object. The parent window is destroyed once the conversion is complete. """ # see selection=="List" in selectRuns method (OK button) intruns = None stringruns = runs.get(1.0, END).split(",") try: intruns = list(map(int, stringruns)) except ValueError: messagebox.showerror("Input Error", "You have inputed "+\ "runs in an incorrect format!") self.runs = intruns parent.destroy()
[docs] def getResultsDBPath(self, parent, update): """Opens a file dialog window that enables user to navigate through the filesystem to select their desired database of results. Expects to receive the parent window of the binding object and a StringVar that is used to represent this path. It will update its value which triggers its trace method, which updates the class attribute used to store the path to the database. """ # see selection=="Results" in selectRuns method (Button e) respath = filedialog.askopenfilename(parent=parent, title="Please select results DB.", initialdir=self.respath) if os.path.isfile(respath): update.set(respath) else: messagebox.showerror("Filename Error!", "Filename does not exist!")