def createButtons(self, frame, vals, text): # create canvas for select all and deselect all buttons canv = Canvas(frame, width=220, height=10) canv.create_line(20, 10, 220, 10, dash=(2, 4)) canv.pack(fill=X) # create each button separately selectAll = Button(frame, text="Select All", command=lambda: self.allButtons(vals, "Select")) selectAll.pack() selectTrialToolTip = ToolTip(selectAll, delay=toolTipDelay, text="Select all " + text + " for analysis.") deselectAll = Button( frame, text="De-Select All", command=lambda: self.allButtons(vals, "De-Select")) deselectAll.pack() deselectTrialToolTip = ToolTip(deselectAll, delay=toolTipDelay, text="Deselect all " + text + " marked for analysis.") return (selectAll, deselectAll)
def addPot(self): potOneVariable = StringVar(self.master) potOneVariable.set(self.potsList[0]) potOneOption = OptionMenu(self.potFrame, potOneVariable, *self.potsList) potOneOption.grid(row=self.potLastRow, column=0) potVariable = DoubleVar() potVariable.trace("w", lambda name, index, mode, potVariable=potVariable: self.potAmountChanged(potVariable)) potOneAmount = Entry(self.potFrame, textvariable=potVariable) #Pad on the right to have space between the pots/envelopes column. potOneAmount.grid(row=self.potLastRow, column=1, padx=(0, 6)) #Create tooltip for Entry potEntryTooltip = ToolTip(potOneAmount, "Enter amount to add/remove") self.potLastRow = self.potLastRow + 1 potWidgets = DoubleValueWidgets(potOneOption, potOneVariable, potOneAmount, potVariable, potEntryTooltip) self.potsWidgets.append(potWidgets) potOneVariable.trace( "w", lambda name, index, mode, potOneVariable=potOneVariable: self. potSelectionChanged(potWidgets)) self.potSelectionChanged(potWidgets) self.setRemovePotButtonState() self.potAmountChanged(None) return potWidgets
def createToolTip(self, widget, text): toolTip = ToolTip(widget) def enter(event): toolTip.showtip(text) def leave(event): toolTip.hidetip() widget.bind('<Enter>', enter) widget.bind('<Leave>', leave) return toolTip
def create_tool_tip(widget, text): toolTip = ToolTip(widget) def enter(event): toolTip.show_tip(text) def leave(event): toolTip.hide_tip() widget.bind('<Enter>', enter) widget.bind('<Leave>', leave)
def addEnvelope(self): envelopeOneVariable = StringVar(self.master) envelopeOneVariable.set(self.envelopeList[0]) envelopeOneOption = OptionMenu(self.envelopeFrame, envelopeOneVariable, *self.envelopeList) #Pad on the left to have space between the pots/envelopes column. envelopeOneOption.grid(row=self.envelopeLastRow, column=0, padx=(6, 0)) envelopeVariable = DoubleVar() envelopeVariable.trace( "w", lambda name, index, mode, envelopeVariable=envelopeVariable: self. envelopeAmountChanged(envelopeVariable)) envelopeOneAmount = Entry(self.envelopeFrame, textvariable=envelopeVariable) envelopeOneAmount.grid(row=self.envelopeLastRow, column=1) #Create tooltip for Entry envelopeEntryTooltip = ToolTip(envelopeOneAmount, "Enter amount to add/remove") self.envelopeLastRow = self.envelopeLastRow + 1 envelopeWidgets = DoubleValueWidgets(envelopeOneOption, envelopeOneVariable, envelopeOneAmount, envelopeVariable, envelopeEntryTooltip) self.envelopesWidgets.append(envelopeWidgets) envelopeOneVariable.trace( "w", lambda name, index, mode, envelopeOneVariable=envelopeOneVariable: self.envelopeSelectionChanged(envelopeWidgets)) self.envelopeSelectionChanged(envelopeWidgets) self.setRemoveEnvelopeButtonState() self.envelopeAmountChanged(None) return envelopeWidgets
def __init__(self, app, index): """ Creates EventWidget for given app at given index """ self.height = 20 self.app = app self.index = index self.event = app.my_order.events[index] self.at = app.my_order.at[index + 1] start = self.at.time current = app.scale.get() passed_time = current - start total_time = self.app.my_order.event_length(self.index) dull = total_time == float("inf") or math.isnan(total_time) actual_time = max(0, min(passed_time, total_time)) self.cooldown = self.app.my_order.get_warp_cooldown(self.index) if app.place_by_time: if not dull: time_width = EventWidget.supply_width + len(self.app.my_order.at_time) * 5 disp = start * 5 - 1 else: time_width = 0 disp = 0 else: if not dull: time_width = max(400, EventWidget.supply_width + max(self.cooldown, total_time) * 5) else: time_width = 400 disp = 0 Canvas.__init__(self, app.event_frame, height=self.height, width=time_width) if self.cooldown and not dull: cooldown_passed = max(0, min(self.cooldown, current - start)) self.cooldown_rect = self.create_rectangle( EventWidget.supply_width + disp, 2, EventWidget.supply_width + self.cooldown * 5 + disp, self.height ) self.cooldown_fill = self.create_rectangle( EventWidget.supply_width + disp, 2, EventWidget.supply_width + cooldown_passed * 5 + disp, self.height, fill="pink", ) if not dull: self.fill = self.create_rectangle( EventWidget.supply_width + disp, 2, actual_time * 5 + EventWidget.supply_width + disp, self.height, fill="aquamarine", disabledoutline="", ) self.create_text(2, 2, text=str(self.at.supply) + "/" + str(self.at.cap), anchor=N + W) if not dull: self.full_time = self.create_rectangle( EventWidget.supply_width + disp, 2, total_time * 5 + EventWidget.supply_width + disp, self.height ) self.create_text(EventWidget.supply_width + 5 + disp, 10, text=events[self.event[0]].name, anchor=W) self.bind("<Button-1>", self.clicked) self.bind("<B1-Motion>", self.drag) self.passed_str = str(actual_time) + "/" + str(total_time) self.tooltip = ToolTip(self, delay=50) self.tooltip.configure(text=self.passed_str + " " + self.app.my_order.get_note(self.index)) self.rMenu = Menu(self, tearoff=0) self.rMenu.add_command(label="Insert above", command=self.insert_above) self.rMenu.add_command(label="Insert below", command=self.insert_below) self.rMenu.add_command(label="Delete", command=self.delete) self.rMenu.add_command(label="Edit note", command=self.note) if app.my_order.can_trick(index): if app.my_order.uses_trick(index): label = "Disable gas trick" else: label = "Enable gas trick" self.rMenu.add_command(label=label, command=self.toggle_trick) self.bind("<Button-3>", self.popup)
class EventWidget(Canvas): """ Represents event in GUI """ supply_width = 60 def __init__(self, app, index): """ Creates EventWidget for given app at given index """ self.height = 20 self.app = app self.index = index self.event = app.my_order.events[index] self.at = app.my_order.at[index + 1] start = self.at.time current = app.scale.get() passed_time = current - start total_time = self.app.my_order.event_length(self.index) dull = total_time == float("inf") or math.isnan(total_time) actual_time = max(0, min(passed_time, total_time)) self.cooldown = self.app.my_order.get_warp_cooldown(self.index) if app.place_by_time: if not dull: time_width = EventWidget.supply_width + len(self.app.my_order.at_time) * 5 disp = start * 5 - 1 else: time_width = 0 disp = 0 else: if not dull: time_width = max(400, EventWidget.supply_width + max(self.cooldown, total_time) * 5) else: time_width = 400 disp = 0 Canvas.__init__(self, app.event_frame, height=self.height, width=time_width) if self.cooldown and not dull: cooldown_passed = max(0, min(self.cooldown, current - start)) self.cooldown_rect = self.create_rectangle( EventWidget.supply_width + disp, 2, EventWidget.supply_width + self.cooldown * 5 + disp, self.height ) self.cooldown_fill = self.create_rectangle( EventWidget.supply_width + disp, 2, EventWidget.supply_width + cooldown_passed * 5 + disp, self.height, fill="pink", ) if not dull: self.fill = self.create_rectangle( EventWidget.supply_width + disp, 2, actual_time * 5 + EventWidget.supply_width + disp, self.height, fill="aquamarine", disabledoutline="", ) self.create_text(2, 2, text=str(self.at.supply) + "/" + str(self.at.cap), anchor=N + W) if not dull: self.full_time = self.create_rectangle( EventWidget.supply_width + disp, 2, total_time * 5 + EventWidget.supply_width + disp, self.height ) self.create_text(EventWidget.supply_width + 5 + disp, 10, text=events[self.event[0]].name, anchor=W) self.bind("<Button-1>", self.clicked) self.bind("<B1-Motion>", self.drag) self.passed_str = str(actual_time) + "/" + str(total_time) self.tooltip = ToolTip(self, delay=50) self.tooltip.configure(text=self.passed_str + " " + self.app.my_order.get_note(self.index)) self.rMenu = Menu(self, tearoff=0) self.rMenu.add_command(label="Insert above", command=self.insert_above) self.rMenu.add_command(label="Insert below", command=self.insert_below) self.rMenu.add_command(label="Delete", command=self.delete) self.rMenu.add_command(label="Edit note", command=self.note) if app.my_order.can_trick(index): if app.my_order.uses_trick(index): label = "Disable gas trick" else: label = "Enable gas trick" self.rMenu.add_command(label=label, command=self.toggle_trick) self.bind("<Button-3>", self.popup) def echo(self, event=None): """ Prints the event's index, useful for testing binding events """ print self.index def chrono_check(self, chrono_index): """ Changes this event to be dashed if able to be Chrono Boosted from chrono_index """ if self.app.my_order.can_chrono(self.index, chrono_index): self.itemconfig(self.full_time, dash=(4, 4)) else: self.itemconfig(self.full_time, dash=None) def clicked(self, click_event): """ On click, check if Chrono Boost is active, and if so, Chrono Boost this event Otherwise, prepare dragging this event to other indexes """ if self.app.chrono >= 0 and self.app.my_order.can_chrono(self.index, self.app.chrono): self.app.insert_chrono(self.index) self.app.chrono = -1 else: self.app.drag = self.index def drag(self, drag_event): """ Calculates mouse position relative to dragged event, moves event if difference is large enough """ change = 0 if self.index == self.app.drag: if drag_event.y > 40: change = (drag_event.y - 13) / 27 elif drag_event.y < -14: change = (drag_event.y + 14) / 27 elif self.index - 1 >= self.app.drag: change = self.index - self.app.drag - int(drag_event.y < 14) elif self.index + 1 <= self.app.drag: change = -(self.app.drag - self.index - int(drag_event.y > 14)) if change: self.app.my_order.move(self.app.drag, self.app.drag + change) self.app.drag += change self.app.refresh() def update(self, current): """ Updates the time completion of this event given current time """ start = self.at.time if self.app.place_by_time: disp = start * 5 - 1 else: disp = 0 passed_time = current - start total_time = self.app.my_order.event_length(self.index) dull = total_time == float("inf") or math.isnan(total_time) actual_time = max(0, min(passed_time, total_time)) if not dull: self.coords( self.fill, EventWidget.supply_width + disp, 2, actual_time * 5 + EventWidget.supply_width + disp, self.height, ) if self.cooldown: cooldown_passed = max(0, min(self.cooldown, current - start)) self.coords( self.cooldown_fill, EventWidget.supply_width + disp, 2, EventWidget.supply_width + cooldown_passed * 5 + disp, self.height, ) self.passed_str = str(actual_time) + "/" + str(total_time) self.tooltip.configure(text=self.passed_str + " " + self.app.my_order.get_note(self.index)) def popup(self, event): """ Creates right-click menu """ self.rMenu.post(event.x_root, event.y_root) def insert_above(self): """ Insert event option above this event """ self.app.insert_event_choose(self.index) def insert_below(self): """ Insert event option below this event """ self.app.insert_event_choose(self.index + 1) def delete(self): """ Remove this event from the build order """ self.app.my_order.delete(self.index) self.app.refresh() def note(self): """ Allow user to edit note describing this event in a separate window """ root = Toplevel() comment = App(root) comment.label = Label(root, text="Comment: ") comment.label.pack(side=LEFT) comment.entry = Entry(root) comment.entry.insert(0, self.app.my_order.get_note(self.index)) comment.entry.pack(padx=3, side=LEFT) def submit(): self.app.my_order.set_note(self.index, comment.entry.get()) self.tooltip.configure(text=self.passed_str + " " + self.app.my_order.get_note(self.index)) comment.master.destroy() comment.button = Button(root, text="OK", command=submit) comment.button.pack(side=LEFT) root.mainloop() def toggle_trick(self): """ Toggles whether or not this event uses extractor trick """ self.app.my_order.toggle_trick(self.index) self.app.refresh()
Entry2Var = StringVar() Entry2Var.trace('w', lambda name, index, mode, Entry2Var=Entry2Var: Entry2callback(Entry2Var)) def Entry2callback(Entry2Var): CheckForMatchInKeyList() # ------------------------------ # Build the gui and start the program # This entry box displays the time and date Entry1 = Entry(Main) Entry1.pack(side=TOP, fill=X, expand=TRUE) ToolTip(Entry1, 'Time and date display') # Enter the search values def ShowCalender(): global CalendarWindow if CalendarWindow: try: CalendarWindow.destroy() except: CalendarWindow = None CalendarWindow = tkinter.Tk() CalendarWindow.title('Tk Calendar') ttkcal = CAL.Calendar(CalendarWindow, firstweekday=calendar.SUNDAY) ttkcal.pack(expand=1, fill='both')
def Entry2Enter(Junk): Entry2.delete(0, tk.END) Entry2.insert(0, DM.EditorResults) CheckForMatchInKeyList() Entry2.focus_force() ToolTip(Entry2, 'Search box (Entry2)')
# ------------------------------ Entry2Var = tk.StringVar() Entry2Var.trace('w', lambda name, index, mode, Entry2Var=Entry2Var: Entry2callback(Entry2Var)) def Entry2callback(Entry2Var): CheckForMatchInKeyList() # ------------------------------ # Build the gui and start the program # This entry box displays the time and date Entry1 = tk.Entry(Main) Entry1.pack(side=tk.TOP, fill=tk.X, expand=tk.TRUE) ToolTip(Entry1, 'Time and date display (Entry1)') # Enter the search values def ShowCalender(): global CalendarWindow if CalendarWindow: try: CalendarWindow.destroy() except Exception as e: print('Unable to read project file\n' + str(e)) CalendarWindow = None CalendarWindow = tkinter.Tk() CalendarWindow.title('Tk Calendar') ttkcal = CAL.Calendar(CalendarWindow, firstweekday=calendar.SUNDAY)
def createComponents(self): # Create text fonts for components self.titleFont = tkFont.Font(family="Arial", size=18) self.componentFont = tkFont.Font(family="Helvetica", size=16) # Create a frame for the title section # ====================================================================== titleFrame = Frame(self) titleFrame.pack(fill=X) # Create the title label title_label = Label(titleFrame, text="Data Processor For Pigeon Experiment", font=self.titleFont) title_label.pack(fill=X, expand=True) title_labelTooltip = ToolTip( title_label, delay=toolTipDelay + 500, text="This program was created by Chris Cadonic for use \ in the laboratory of Dr. Debbie Kelly.") # Create a canvas for drawing a separation line canv = Canvas(titleFrame, width=840, height=10) canv.create_line(0, 10, 840, 10) canv.pack(fill=X, anchor=CENTER, expand=True) # Create a frame for the bottom section # ====================================================================== footerFrame = Frame(self) footerFrame.pack(anchor=S, expand=True, side=BOTTOM) # Create a run button runButton = Button(footerFrame, width=200, text="Run Processing", command=self.run) runButton.pack(fill=Y) runToolTip = ToolTip( runButton, delay=toolTipDelay, text="Run analysis based on the groups and animals\ selected above.") # Create and populate group and trial button frames # ====================================================================== trialFrame = Frame(self) trialFrame.pack(expand=True, anchor=W, side=LEFT) # Create a checkbox for each test group self.trialLabels = [ "Non-reinforced training", "Control 1", "Control 2", "Feature Only", "Geometry Only", "Affine" ] self.trialKeys = ["Nrtr", "C1", "C2", "FO", "GO", "AF"] self.trialTooltips = [ "Non-reinforced training group.", "Control group 1", "Control group 2", "Group where an extra wall and a \ feature wall are placed in the environment to create an enclosed square.", "Group where the feature wall is removed, but the geometry of the environment \ remains the same.", "Group where the feature wall is moved to the end of the \ long wall." ] self.trialVals = [] # create all of the group buttons for num in range(len(self.trialLabels)): self.trialVals.append(IntVar()) trialButtons.append( Checkbutton(trialFrame, text=self.trialLabels[num], variable=self.trialVals[num], font=self.componentFont)) trialButtons[-1].pack(pady=8) trialButtonTooltips.append( ToolTip(trialButtons[-1], delay=toolTipDelay, text=self.trialTooltips[num])) # create select/deselect all buttons self.createButtons(trialFrame, self.trialVals, "experimental phases") # Create a frame for handling all of the birds # ====================================================================== animalsFrame = Frame(self, width=100, height=360) animalsFrame.pack(expand=True, anchor=CENTER, side=RIGHT) self.animalCanvas = Canvas(animalsFrame, width=100, height=360, scrollregion=(0, 0, 500, 1000)) self.newFrame = Frame(self.animalCanvas, width=100, height=360) self.animalScrollbar = Scrollbar(animalsFrame, orient="vertical", command=self.animalCanvas.yview) self.animalCanvas.configure(yscrollcommand=self.animalScrollbar.set) self.animalScrollbar.pack(side="right", fill="y") self.animalCanvas.pack(side="top") self.animalCanvas.create_window((0, 0), window=self.newFrame, anchor='nw') self.newFrame.bind("<Configure>", self.scrollFunc) self.animals = list(allData.keys()) self.animalVals = [] # Create a button for each bird in the data directory for bird in range(len(self.animals)): self.animalVals.append(IntVar()) animalButtons.append( Checkbutton(self.newFrame, text=self.animals[bird], variable=self.animalVals[bird], font=self.componentFont)) self.animalVals[-1].set(1) animalButtons[-1].pack(pady=6) # create select/deselect all buttons self.createButtons(animalsFrame, self.animalVals, "animals") # Create a frame for handling all of the additional buttons # ====================================================================== buttonsFrame = Frame(self) buttonsFrame.pack(fill=X, expand=True) # Threshold label thresholdLabel = Label(buttonsFrame, text="Change threshold: ") # Threshold entry box thresholdBox = Entry(buttonsFrame, width=10) thresholdBox.pack() thresholdBox.insert(0, defaultThreshold) thresholdBoxTooltip = ToolTip( thresholdBox, delay=toolTipDelay, text="Change this value to set a new threshold value \ for calculating the max distance away from a goal to be kept for data analysis." ) # Re-analyze with new thresholdBox reformatButton = Button( buttonsFrame, text="Apply new threshold", command=lambda: self.checkReformat(thresholdBox, False)) reformatButton.pack() reformatTooltip = ToolTip( reformatButton, delay=toolTipDelay, text="Click to apply any changes to threshold box above.") # Reset threshold to defaultThreshold resetButton = Button( buttonsFrame, text="Reset threshold and run", command=lambda: self.checkReformat(thresholdBox, True)) resetButton.pack() resetButtonTooltip = ToolTip( resetButton, delay=toolTipDelay, text="Click to reset threshold to default value.") # Create a sort button self.sortOutput = IntVar() sortButton = Checkbutton(buttonsFrame, text="Sort", variable=self.sortOutput, font=self.componentFont) sortButton.pack() sortTooltip = ToolTip( sortButton, delay=toolTipDelay, text="Select to auto-sort the output excel spreadsheets by \ trial type.") # Create a quit button quitButton = Button(buttonsFrame, text="Quit", command=self.quit) quitButton.pack() quitToolTip = ToolTip(quitButton, delay=toolTipDelay, text="Quit the program and close the GUI.")