def settings(): global settings_popup try: settings_popup.destroy() except: pass settings_styles = Style() settings_styles.configure( "SettingsLabelframe.TLabelframe.Label", font=("Verdana", 18, "normal")) settings_styles.configure( "SettingsLabelframe.TLabelframe.Label", foreground=COLORS['TEXTCOLOR']) settings_popup = Toplevel() settings_popup.title("Settings") settings_popup.transient(root) settings_popup.resizable(False, False) other_frame = LabelFrame(settings_popup, text="Settings", style="SettingsLabelframe.TLabelframe") basefreq_lbl = Label(other_frame, text="Octave") basefreq_om = OptionMenu(other_frame, OPTIONS['BASE_FREQ'], BASE_FREQS[-1], *BASE_FREQS) basefreq_lbl.grid(row=0, column=0, padx=5) basefreq_om.grid(row=0, column=1, padx=5) other_frame.pack(padx=15, pady=15, ipadx=5, ipady=5) settings_popup.mainloop()
def add_set_selector(self, model_variable, standard, wild): set_selector = OptionMenu(self, model_variable, "Card Set", *standard, *wild) # Fix for multi-menu bug optionmenu_patch(set_selector, model_variable) set_selector['menu'].insert_separator(len(standard)) set_selector.grid(row=2, column=1, columnspan=2, pady=20) self.set_selector = set_selector
class OtherMiniView(View): def __init__(self, master): super().__init__(master) self.master = master self.name = 'Other' self.folder_selection = None self.size_grid(3, 1) # TODO: set selector is a little bit WET, may want a very minor refactor def add_selector(self, variable, *options): # Folder selection is a dropdown of any output folder not in ['packs', 'arena', 'rewards'] # Selection of a folder, and hitting save just auto-routes the image to the correct folder # Config is used by the model to determine any sub-folders by year/month self.folder_selection = OptionMenu(self, variable, "Folder", *options) self.folder_selection.grid(row=1, column=0, sticky=NSEW)
class RewardBox(View): def __init__(self, master): super().__init__(master) self.master = master self.name = 'Reward Box' self.reward_dropdown = None edge_color = '#2d2d89' self.config(highlightbackground=edge_color, highlightthickness=1) self.reward_entry_frame = Frame(self) self.reward_entry_frame.grid(row=1, column=0) label = Label(self.reward_entry_frame, text='Hello') label.pack() self.size_grid(2, 1) def add_reward_dropdown(self, model_variable, default, options): self.reward_dropdown = OptionMenu(self, model_variable, default, *options) # Using patch to fix bug with multiple menus optionmenu_patch(self.reward_dropdown, model_variable) self.reward_dropdown.grid(row=0, column=0)
class VoxGrab(Frame): def __init__(self, master=None): # Inherit from frame Frame.__init__(self, master) self.master = master self.queue = queue.Queue() # String vars self.directory = StringVar() self.status = StringVar() self.language = StringVar() self.language.set('EN') self.status.set("Please choose a folder") # Pseudo booleans self.check_flag = IntVar() self.check_flag.set(1) self.files = [] # Get languages try: self.languages = SubtitleDownloader.get_languages() # First element must be null, because tkinter makes no sense self.languages.insert(0, None) except Exception as e: msg = "Error when fetching languages, defaulting to English\n" \ + str(e) messagebox.showerror("Connection error", msg) self.languages = ['en'] # Create widgets # The "important" widgets needed later self.status_label = Label(self.master, textvariable=self.status) self.progress_bar = ttk.Progressbar(self.master, orient="horizontal", mode="determinate", length=620) self.file_area = Frame(self.master) self.folder_fame = Frame(self.master) self.button_frame = Frame(self.master) self.language_selector = OptionMenu(self.button_frame, self.language, *self.languages) self.canvas = Canvas(self.file_area, borderwidth=0, background=COLORS['grey'], width=600, height=400) self.file_frame = Frame(self.canvas) self.create_widgets() def create_widgets(self): """Create widgets, saves init from becoming ridiculous""" # Create labels title_label = Label(self.master, text='VoxGrab\nsubtitle downloader', font=16) # Create folder text input frame Entry(self.folder_fame, width=80, textvariable=self.directory).grid(column=0, row=1, padx=0, sticky=W) ttk.Button(self.folder_fame, text='Load files', command=self.load_files).grid(column=1, row=1, padx=10) # Create scrolling area and scroll bar scrollbar = Scrollbar(self.file_area, orient='vertical', command=self.canvas.yview) # Add title labels for columns Label(self.file_frame, text="File name", width="70", borderwidth="1", relief="solid").grid(row=0, column=0) Label(self.file_frame, text="Status", width="14", borderwidth="1", relief="solid").grid(row=0, column=1) # Configure, create & pack self.canvas.configure(yscrollcommand=scrollbar.set) self.canvas.create_window((4, 4), window=self.file_frame, anchor='nw', tags='self.file_frame') self.canvas.pack(side=LEFT) scrollbar.pack(side=RIGHT, fill=Y) # Create button pane Checkbutton(self.button_frame, text='Skip downloaded subs', variable=self.check_flag, justify=LEFT).grid(column=0, row=1, padx=10, sticky=W) Label(self.button_frame, text='Language:').grid(column=1, row=1) self.language_selector.grid(column=2, row=1, sticky=W) ttk.Button(self.button_frame, text='Choose folder', command=self.prompt_directory).grid(column=4, row=1, padx=10, sticky=E) ttk.Button(self.button_frame, text="Download subs", command=self.download_subs).grid(column=5, row=1, padx=10, sticky=E) self.button_frame.grid_columnconfigure(3, minsize=120) # Pack it all title_label.pack(pady=5) self.file_area.pack(padx=15, pady=5) self.progress_bar.pack() self.status_label.pack(pady=5) self.folder_fame.pack(pady=5) self.button_frame.pack(pady=5) # Bind scrolling self.file_frame.bind("<Configure>", self.onFrameConfigure) self.file_frame.bind('<Enter>', self._bound_to_mousewheel) self.file_frame.bind('<Leave>', self._unbound_to_mousewheel) self.master.bind('<Return>', self.load_files) def onFrameConfigure(self, event): """Reset the scroll region to encompass the inner file_frame""" self.canvas.configure(scrollregion=self.canvas.bbox("all")) def _bound_to_mousewheel(self, event): """Bind mousewheel to scroll function""" self.canvas.bind_all("<MouseWheel>", self._on_mousewheel) def _unbound_to_mousewheel(self, event): """Unbind mousewheel""" self.canvas.unbind_all("<MouseWheel>") def _on_mousewheel(self, event): """Scrolling function""" self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units") def prompt_directory(self): """Prompt for directory, load files and populate gui""" self.directory.set(filedialog.askdirectory()) self.load_files() def load_files(self, *args): try: self.files = self.sort_files(os.listdir(path=self.directory.get())) self.populate() if len(self.files) > 0: self.status.set("Click Download") else: self.status.set("No media in folder") except FileNotFoundError: self.status.set("That's not a folder") def clear_download_frame(self): """Clears file_frame""" for widget in self.file_frame.winfo_children(): widget.destroy() def populate(self): """Populate/refresh file_frame""" self.clear_download_frame() # Re-create title labels for columns Label(self.file_frame, text="File name", width="70", borderwidth="1", relief="solid").grid(row=0, column=0) Label(self.file_frame, text="Status", width="14", borderwidth="1", relief="solid").grid(row=0, column=1) for i, file in enumerate(self.files): Label(self.file_frame, text=file["fileName"], width=70, borderwidth="1", relief="solid").grid(row=i+1, column=0) Label(self.file_frame, text=file["status"], width="14", borderwidth="1", relief="solid", bg=file["color"]).grid(row=i+1, column=1) file["row"] = i+1 @staticmethod def sort_files(files): """Sort out non media files""" media_files = [] for file in files: media_re = re.search(r"^[\s\S]*?\.(mp4|avi|mkv|m4v)$", file) if media_re: context = {"fileName": file, "status": "Waiting", "color": COLORS["azure"]} media_files.append(context) else: pass return media_files def download_subs(self): """ Attempt to download subs to all files in self.files and set status label """ if len(self.files) > 0: # Prepare downloader os.chdir(self.directory.get()) downloader = SubtitleDownloader(self.check_flag.get(), lang=self.language.get()) for _file in self.files: self.queue.put(_file) parent_thread = threading.Thread(target=self._parent, args=(downloader, )) parent_thread.start() else: self.status.set('No subtitles to download') def _parent(self, downloader): """ Parent thread for maneging workers. Allows for the UI to be update once the download is completed without blocking the GUI thread :param downloader: SubtitleDownloader to be handed over to workers :return: None """ threads = [] # Prepare the GUI self.progress_bar.configure(maximum=len(self.files)) self.status.set('Downloading subtitles.') for child in (self.folder_fame.winfo_children() + self.button_frame.winfo_children()): child.configure(state=DISABLED) # Start threads for n in range(min(10, len(self.files))): thread = threading.Thread(target=self._worker, args=(downloader,)) thread.start() threads.append(thread) # Wait for them to finish for thread in threads: thread.join() # Update GUI for child in (self.folder_fame.winfo_children() + self.button_frame.winfo_children()): child.configure(state=NORMAL) self.status.set('Done!') def _worker(self, downloader): """ Worker thread downloading subtitles also updates the file_frame labels and progress bar :param downloader: SubtitleDownloader for API interaction :return: None """ while True: # Get a move file from queue try: _file = self.queue.get(block=False) except queue.Empty: return # Download sub downloader.download_sub(_file) # Replace the corresponding label label_config = { 'text': _file['status'], 'width': 14, 'borderwidth': '1', 'relief': 'solid', 'bg': _file['color'] } Label(self.file_frame, **label_config).grid(row=_file["row"], column=1) self.progress_bar.step()
class App(ThemedTk): ''' This class is neatly wraps all the functionality of our application. By itself, it's is responsible for handling command line input, navigating between files, navigating between frames, handling of some events, and coordinating other core functionality (which is handled by individual `modules`). Note: - when we change files, modules should execute MODULE.reset() methods - when we change frames, modules should execute MODULE.update() methods - modules that are responsible for managing their own widgets should have MODULE.grid() and MODULE.grid_remove() methods to wrap corresponding functionality for their widgets ''' def __init__(self): info('initializing UltraTrace') default_ttktheme = "clam" # alt, clam, classic, default # do the normal Tk init stuff if util.get_platform() == 'Linux': try: info(' - loading platform-specific enhancements for Linux') import xrp # pip3 install xparser from pathlib import Path XresPath = os.path.join(str(Path.home()), '.Xresources') if os.path.isfile(XresPath) or os.path.islink(XresPath): info(" - found .Xresources file: {}".format(XresPath)) Xresources = xrp.parse_file(XresPath, encoding="utf8") #info("Opened .Xresources file {}".format(XresPath)) if '*TtkTheme' in Xresources.resources: ttktheme = Xresources.resources['*TtkTheme'] if ttktheme in THEMES: info(" - setting Linux Ttk theme to {}".format( ttktheme)) else: warn( " - Ttk theme {} specified ~/.Xresources not available, defaulting to {}" .format(ttktheme, default_ttktheme)) ttktheme = default_ttktheme elif '*TkTheme' in Xresources.resources: ttktheme = Xresources.resources['*TkTheme'] info(" - setting Linux Tk theme to {}".format( ttktheme)) else: ttktheme = default_ttktheme info( " - falling back to default Linux Tk theme: {}. You can set your theme to something else by adding a line like \"*TkTheme: alt\" or \"*TtkTheme: arc\" to ~/.Xresources" .format(ttktheme)) else: ttktheme = "clam" # alt, clam, classic, default info( " - no ~/.Xresources file found; falling back to default Linux Tk theme: {}. You can set your theme to something else by adding a line like \"*TkTheme: alt\" or \"*TtkTheme: arc\" to ~/.Xresources" .format(ttktheme)) super().__init__(theme=ttktheme) except Exception as e: error( "Crash while loading .Xresources file or initialising T(t)k theme", e) super().__init__() else: super().__init__() self.title('UltraTrace') # check if we were passed a command line argument parser = argparse.ArgumentParser(prog='UltraTrace') parser.add_argument( 'path', help= 'path (unique to a participant) where subdirectories contain raw data', default=None, nargs='?') args = parser.parse_args() # initialize data module self.Data = modules.Metadata(self, args.path) # initialize the main app widgets self.setWidgetDefaults() self.buildWidgetSkeleton() # initialize other modules self.Control = modules.Control(self) self.Trace = modules.Trace(self) self.Dicom = modules.Dicom(self) self.Audio = modules.Playback(self) self.TextGrid = modules.TextGrid(self) self.Spectrogram = modules.Spectrogram(self) self.Search = modules.Search(self) info(' - loading widgets') self.filesUpdate() # self.framesUpdate() # self.TextGrid.startup() #NOTE why does modules.TextGrid have to reset a second time? Is there a more economical way to do this? # to deal with resize handler being called multiple times # in a single window resize self.isResizing = False self.oldwidth = self.winfo_width() self.after(300, self.afterstartup) def setWidgetDefaults(self): ''' Need to set up some defaults here before building Tk widgets (this is specifically true w/r/t the StringVars) ''' self.currentFID = 0 # file index w/in list of sorted files self.frame = 0 # current frame of dicom file self.isClicked = False # used in handling of canvas click events self.isDragging = False # used in handling of canvas click events # self.resized = False #for changing widgets after window resize self.selectBoxX = False self.selectBoxY = False # some styling self.fontStyle = Style() if util.get_platform() == 'Darwin': self.fontStyle.configure('symbol.TButton', font=('DejaVu Serif', 26)) else: self.fontStyle.configure('symbol.TButton', font=('DejaVu Serif', 19)) # declare string variables self.currentFileSV = StringVar(self) self.frameSV = StringVar(self) # initialize string variables self.currentFileSV.set(self.Data.files[self.currentFID]) self.frameSV.set('1') def buildWidgetSkeleton(self): ''' Builds the basic skeleton of our app widgets. - items marked with (*) are built directly in this function - items marked with (~) are built by the individual modules # WARNING: out of date diagram .________________________________________. | ROOT | | .____________________________________. | | | TOP* | | | | ._______________. .______________. | | | | | LEFT* | | RIGHT* | | | | | | - file nav* | | - dicom~ | | | | | | - frame nav*| | | | | | | | - traces~ | | | | | | | | - undo~ | | | | | | | \_______________/ \______________/ | | | \____________________________________/ | | | | .____________________________________. | | | BOTTOM* | | | | - spectrogram~ | | | | - textgrid~ | | | \____________________________________/ | \________________________________________/ ''' # main Frame skeleton self.TOP = Frame(self) self.TOP.columnconfigure(1, weight=1, minsize=320) self.TOP.rowconfigure(0, weight=1, minsize=240) self.LEFT = Frame(self.TOP) # self.LEFT.rowconfigure(0,weight=1) # self.LEFT.columnconfigure(0,weight=1) self.RIGHT = Frame(self.TOP) self.RIGHT.rowconfigure(0, weight=1) self.RIGHT.columnconfigure(0, weight=1) self.BOTTOM = Frame(self) # self.BOTTOM.columnconfigure(0,weight=1) self.BOTTOM.columnconfigure(1, weight=1) # self.BOTTOM.rowconfigure(0,weight=1) # self.TOP.grid( row=0, column=0, sticky='nw') # self.LEFT.grid( row=0, sticky='n' ) # self.RIGHT.grid( row=0, column=1) # self.BOTTOM.grid( row=1, column=0, sticky='e') self.TOP.grid(row=0, column=0, sticky='nesw') self.LEFT.grid(row=0, sticky='nesw') self.RIGHT.grid(row=0, column=1, sticky='nesw') self.BOTTOM.grid(row=1, column=0, sticky='nesw') self.pady = 3 self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) # navigate between all available filenames in this directory self.filesFrame = Frame(self.LEFT) #, pady=7) self.filesPrevBtn = Button(self.filesFrame, text='<', command=self.filesPrev, takefocus=0, width="1.5") self.filesJumpToMenu = OptionMenu(self.filesFrame, self.currentFileSV, self.Data.files[0], *self.Data.files, command=self.filesJumpTo) self.filesNextBtn = Button(self.filesFrame, text='>', command=self.filesNext, takefocus=0, width="1.5") self.filesFrame.grid(row=1) self.filesPrevBtn.grid(row=1, column=0) self.filesJumpToMenu.grid(row=1, column=1) self.filesNextBtn.grid(row=1, column=2) Header(self.filesFrame, text="Recording").grid(row=0, column=0, columnspan=3) # navigate between frames self.framesFrame = Frame(self.LEFT) #, pady=7) self.framesSubframe = Frame(self.framesFrame) self.framesPrevBtn = Button(self.framesSubframe, text='<', command=self.framesPrev, takefocus=0, width="1.5") self.framesEntryText = Entry(self.framesSubframe, width=5, textvariable=self.frameSV) self.framesEntryBtn = Button(self.framesSubframe, text='Go', command=self.framesJumpTo, takefocus=0, width="3") self.framesNextBtn = Button(self.framesSubframe, text='>', command=self.framesNext, takefocus=0, width="1.5") self.framesHeader = Header(self.framesFrame, text="Frame") self.framesFrame.grid(row=3) self.framesSubframe.grid(row=1) # non-module-specific bindings if util.get_platform() == 'Linux': self.bind('<Control-Left>', self.filesPrev) self.bind('<Control-Right>', self.filesNext) else: self.bind('<Option-Left>', self.filesPrev) self.bind('<Option-Right>', self.filesNext) self.bind('<Left>', self.framesPrev) self.bind('<Right>', self.framesNext) self.bind('<BackSpace>', self.onBackspace) self.bind('<Button-1>', self.getWinSize) self.bind('<ButtonRelease-1>', self.onRelease) self.bind('<Double-Button-1>', self.onDoubleClick) self.bind('<Escape>', self.onEscape) # self.count = 0 self.framesEntryText.bind('<Return>', self.unfocusAndJump) self.framesEntryText.bind('<Escape>', lambda ev: self.framesFrame.focus()) # force window to front self.lift() def lift(self): ''' Bring window to front (doesn't shift focus to window) ''' self.attributes('-topmost', 1) self.attributes('-topmost', 0) def afterstartup(self): ''' ''' self.bind('<Configure>', self.alignBottomLeftWrapper) self.alignBottomLeft() self.getWinSize() self.alignBottomRight(self.oldwidth - self.leftwidth) if self.Dicom.zframe.image: self.Dicom.zframe.setImage(self.Dicom.zframe.image) def alignBottomLeftWrapper(self, event=None): if self.isResizing: return self.isResizing = True self.after(100, lambda: self.alignBottomLeft(event)) def alignBottomLeft(self, event=None): ''' Makes the length of the canvases on the lower left the same length as the pane of controls in self.LEFT ''' self.leftwidth = self.LEFT.winfo_width() for t in range(len(self.TextGrid.TkWidgets)): tierWidgets = self.TextGrid.TkWidgets[t] if 'frames' in tierWidgets: tierWidgets['frames-label'].config(width=self.leftwidth) tierWidgets['frames-label'].coords( 'all', (self.leftwidth, tierWidgets['frames-label'].coords(1)[1])) if 'canvas' in tierWidgets: tierWidgets['canvas-label'].config(width=self.leftwidth) tierWidgets['canvas-label'].coords( 'all', (self.leftwidth, tierWidgets['canvas-label'].coords(1)[1])) if event == None or event.widget == self: self.alignBottomRight(self.winfo_width() - self.leftwidth) if self.Dicom.zframe.image: self.Dicom.zframe.setImage(self.Dicom.zframe.image) self.isResizing = False def alignBottomRight(self, x): ''' ''' self.Spectrogram.canvas_width = x self.Spectrogram.canvas.config(width=x) self.TextGrid.canvas_width = x for t in range(len(self.TextGrid.TkWidgets)): tierWidgets = self.TextGrid.TkWidgets[t] canvas = None if 'frames' in tierWidgets: tierWidgets['frames'].config(width=x) elif 'canvas' in tierWidgets: tierWidgets['canvas'].config(width=x) if 'times' in tierWidgets: tierWidgets['times'].config(width=x) tierWidgets['times'].coords( 2, (x, tierWidgets['times'].coords(2)[1])) #move end time tierWidgets['times'].coords( 3, (x / 2, tierWidgets['times'].coords(3)[1])) self.TextGrid.fillCanvases() #calls Spectrogram.reset # def onWindowResize(self, event): # ''' # Handle moving or resizing the app window # ''' # self.alignBottomLeft() # # self.resized=True def getWinSize(self, event=None): self.oldwidth = self.winfo_width() def onDoubleClick(self, event): ''' select only crosshairs that's double clicked''' nearby = self.Trace.getNearClickAllTraces((event.x, event.y)) if nearby != None: self.Trace.unselectAll() self.Trace.select(nearby) def onClickZoom(self, event): ''' Handle clicking within the zoomframe canvas ''' if self.Dicom.isLoaded(): self.click = (event.x, event.y) self.isDragging = False # get nearby crosshairs from this trace nearby = self.Trace.getNearClickAllTraces(self.click) # if we didn't click near anything ... if nearby == None: self.Trace.unselectAll() if event.state != 17: # unselect crosshairs self.isClicked = True ch = self.Trace.add(*self.click) self.Control.push({'type': 'add', 'chs': [ch]}) else: self.selectBoxX = self.Dicom.zframe.canvas.canvasx(event.x) self.selectBoxY = self.Dicom.zframe.canvas.canvasy(event.y) return # NOTE: only get here if we clicked near something # if holding option key, unselect the guy we clicked on # if event.state == 16: # if holding shift key (event.state==17), and crosshair is selected, unselect it #debug(event.state) if event.state == 17 and nearby in self.Trace.selected: nearby.unselect() if nearby in self.Trace.selected: self.Trace.selected.remove(nearby) # otherwise, if not selected, add it to our selection elif nearby not in self.Trace.selected: #debug("event.state", event.state) if event.state != 1: #and nearby.isSelected == False: self.Trace.unselectAll() # add this guy to our current selection self.Trace.select(nearby) #through all of these operations, if clicked ch is selected, is ready to be dragged if nearby in self.Trace.selected: # set dragging variables self.isDragging = True self.dragClick = self.click def onReleaseZoom(self, event): ''' Handle releasing a click within the zoomframe canvas ''' if self.Dicom.isLoaded(): # select multiple crosshairs if self.selectBoxX != False: canvas = self.Dicom.zframe.canvas x1 = self.selectBoxX x2 = canvas.canvasx(event.x) y1 = self.selectBoxY y2 = canvas.canvasy(event.y) self.selectBoxX = False self.selectBoxY = False trace = self.Trace.getCurrentTraceName() coords = [] x1True = None if trace in self.Trace.crosshairs: for ch in self.Trace.crosshairs[trace]: if x1True == None: x1True, y1True = ch.transformCoordsToTrue(x1, y1) x2True, y2True = ch.transformCoordsToTrue(x2, y2) if ch.isVisible: x, y = ch.getTrueCoords() if min(x1True, x2True) < x < max(x1True, x2True) and min( y1True, y2True) < y < max( y1True, y2True): self.Trace.select(ch) self.isDragging = False self.isClicked = False self.Trace.write() def onReleaseSpec(self, event): '''shift + release zooms textgrid & spectrogram to selected interval''' if self.Spectrogram.specClick == True: # if event.state==257: canvas = self.Spectrogram.canvas t1 = self.Spectrogram.clicktime t2 = self.Spectrogram.xToTime(canvas.canvasx(event.x)) # self.TextGrid.start = float(min(t1,t2)) # self.TextGrid.end = float(max(t1,t2)) # for itm in canvas.find_all()[0]: # for tag in canvas.gettags(itm): #canvas.dtag() does not seem to work with one argument if max(t1, t2) - min( t1, t2 ) > self.Spectrogram.ts: #if selected area is larger than one strip of Spectrogram #gets rid of previous tags for tag in canvas.gettags(canvas.find_all()[0]): canvas.dtag(canvas.find_all()[0], tag) a = self.Spectrogram.timeToX(self.Spectrogram.clicktime) b = event.x x1 = min(a, b) x2 = max(a, b) #find all frames within range, and add them as tags frame_i = self.TextGrid.frames_canvas.find_all()[0] current_loc = self.TextGrid.frames_canvas.coords(frame_i)[0] while current_loc < x2: if current_loc > x1: tag = self.TextGrid.frames_canvas.gettags(frame_i)[0] canvas.addtag_all(tag) frame_i += 1 current_loc = self.TextGrid.frames_canvas.coords( frame_i)[0] canvas.addtag_all('minTime' + str(self.Spectrogram.xToTime(x1))) canvas.addtag_all('maxTime' + str(self.Spectrogram.xToTime(x2))) self.TextGrid.selectedItem = (canvas, canvas.find_all()[0]) self.TextGrid.setSelectedIntvlFrames( self.TextGrid.selectedItem) # self.TextGrid.paintCanvases() # self.Spectrogram.drawInterval(l_loc=x1,r_loc=x2) # debug(canvas.gettags('all')) # specgram = self.Spectrogram.canvas.find_all()[0] # self.TextGrid.fillCanvases() self.TextGrid.genFrameList(widg=canvas, x_loc=x2, SI=True) self.Spectrogram.specClick = False self.Spectrogram.clicktime = -1 def onRelease(self, event): ''' ''' #runs if click happened on specific canvases self.onReleaseZoom(event) self.onReleaseSpec(event) #runs if window resized # if self.resized == True and self.Dicom.zframe.shown == True: #shouldn't trigger when frame not displayed if self.winfo_width( ) != self.oldwidth and self.Dicom.zframe.shown == True: #shouldn't trigger when frame not displayed # self.resized = False #resize dicom image png_loc = self.Data.getPreprocessedDicom(self.frame) image = PIL.Image.open(png_loc) self.Dicom.zframe.setImage(image) # x = self.Dicom.zframe.width x = self.winfo_width() - self.LEFT.winfo_width() # y = self.Dicom.zframe.height #resize TextGrid tiers and spectrogram self.alignBottomRight(x) #move Traces self.Trace.move() #save layout ot geometry manager geometry = self.geometry() self.Data.setTopLevel('geometry', geometry) def onMotion(self, event): ''' Handle mouse movement within the zoomframe canvas ''' if self.Dicom.isLoaded(): if self.isDragging: # dragging selection thisClick = (event.x, event.y) selected = list(self.Trace.selected) coords = [] # move all currently selected crosshairs for sch in selected: # keep their relative distance constant center = (sch.x, sch.y ) # canvas coordinates not true coordinates newX = event.x + center[0] - self.dragClick[0] newY = event.y + center[1] - self.dragClick[1] sch.dragTo((newX, newY)) coords.append(center) self.dragClick = thisClick self.Control.push({ 'type': 'move', 'chs': selected, 'coords': coords }) elif self.isClicked: # no selection, mouse clicked lastClick = self.click thisClick = (event.x, event.y) # enforce minimum distance b/w new crosshairs dx = abs(thisClick[0] - lastClick[0]) / self.Dicom.zframe.imgscale dy = abs(thisClick[1] - lastClick[1]) / self.Dicom.zframe.imgscale if dx > util.CROSSHAIR_DRAG_BUFFER or dy > util.CROSSHAIR_DRAG_BUFFER: self.click = thisClick ch = self.Trace.add(*self.click) self.Control.push({'type': 'add', 'chs': [ch]}) def onEscape(self, event): ''' Handle <Esc> key : empties the current selection ''' self.isDragging = False self.isClicked = False self.Trace.unselectAll() def onBackspace(self, event): ''' Handle <Backspace> key : removes current selection ''' for sch in self.Trace.selected: self.Trace.remove(sch) self.Control.push({'type': 'delete', 'chs': self.Trace.selected}) self.Trace.unselectAll() def filesUpdate(self): ''' Changes to be executed every time we change files ''' # update variables self.currentFileSV.set(self.Data.files[self.currentFID]) self.frame = 1 self.frames = 1 # reset modules self.Control.reset() self.Trace.reset() self.Dicom.reset( ) # need this after Trace.reset() #NOTE is this still true? self.Audio.reset() self.TextGrid.reset() self.Spectrogram.reset() # check if we can pan left/right self.filesPrevBtn['state'] = 'disabled' if self.Data.getFileLevel( '_prev') == None else 'normal' self.filesNextBtn['state'] = 'disabled' if self.Data.getFileLevel( '_next') == None else 'normal' #load first frame self.framesUpdate() def filesPrev(self, event=None): ''' controls self.filesPrevBtn for panning between available files ''' if self.Data.getFileLevel('_prev') != None: # change the index of the current file self.currentFID -= 1 # update self.filesUpdate() def filesNext(self, event=None): ''' controls self.filesNextBtn for panning between available files ''' if self.Data.getFileLevel('_next') != None: # change the index of the current file self.currentFID += 1 # update self.filesUpdate() def filesJumpTo(self, choice): ''' jump directly to an available file (from the OptionMenu widget) ''' self.currentFID = self.Data.files.index(choice) self.filesUpdate() def framesUpdate(self): ''' Changes to be executed every time we change frames ''' # frameTier = self.TextGrid.TextGrid.getFirst(self.TextGrid.frameTierName) # if # update variables self.frameSV.set(str(self.frame)) # update modules self.Control.update() self.Dicom.update() self.Trace.update() self.Audio.update() self.TextGrid.update() self.Spectrogram.update() # check if we can pan left/right self.framesPrevBtn[ 'state'] = 'disabled' if self.frame == self.TextGrid.startFrame else 'normal' self.framesNextBtn[ 'state'] = 'disabled' if self.frame == self.TextGrid.endFrame else 'normal' def framesPrev(self, event=None): ''' controls self.framesPrevBtn for panning between frames ''' # if self.Dicom.isLoaded and self.frame > self.TextGrid.startFrame: if isinstance(self.focus_get(), (Entry, Spinbox)): return if self.frame > self.TextGrid.startFrame: self.frame -= 1 # if len(self.TextGrid.selectedIntvlFrames) != 0: # while str(self.frame) not in self.TextGrid.selectedIntvlFrames or self.frame > self.TextGrid.last_frame: # if self.frame <= int(self.TextGrid.selectedIntvlFrames[0]): # self.frame = int(self.TextGrid.selectedIntvlFrames[0]) # break # self.frame -= 1 self.framesUpdate() def framesNext(self, event=None): ''' controls self.framesNextBtn for panning between frames ''' # if self.Dicom.isLoaded and self.frame < self.TextGrid.endFrame: if isinstance(self.focus_get(), (Entry, Spinbox)): return if self.frame < self.TextGrid.endFrame: self.frame += 1 # if len(self.TextGrid.selectedIntvlFrames) != 0: # while str(self.frame) not in self.TextGrid.selectedIntvlFrames or self.frame < self.TextGrid.first_frame: # if self.frame >= int(self.TextGrid.selectedIntvlFrames[-1]): # self.frame = int(self.TextGrid.selectedIntvlFrames[-1]) # break # self.frame += 1 self.framesUpdate() def unfocusAndJump(self, event): self.framesJumpTo() self.framesFrame.focus() def framesJumpTo(self): ''' jump directly to a frame (from the Entry widget) ''' try: choice = int(self.frameSV.get()) if choice < 1: self.frame = 1 elif choice > self.frames: self.frame = self.frames else: self.frame = choice self.framesUpdate() except ValueError: error('Please enter an integer!')
class ManualIntegrationPage(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.controller = parent title = Label(self,text="Manual Integration",font=("Arial",14,"bold")) title.grid(row=0,column=0,columnspan=6) self.f = Figure(figsize=(5,5), dpi=100) self.a = self.f.add_subplot(111) Label(self, text="Match to Element", font=("Arial",14)).grid(row=1,column=5) Label(self, text="Lower Bound: ").grid(row=7,column=0) self.lowerBound = Entry(self) self.lowerBound.grid(row=7,column=1) Label(self, text="Upper Bound: ").grid(row=7,column=2) self.upperBound = Entry(self) self.upperBound.grid(row=7,column=3) integrateButton = Button(self, text="Integrate", command = self.submit) integrateButton.grid(row=7,column=4) Button(self, text="Back",command=self.back).grid(row=8,column=0) self.curMenu = None def populate_values(self, energies, cps): self.energies = energies self.cps = cps self.a.cla() self.a.plot(energies, cps,"b-") self.canvas = FigureCanvasTkAgg(self.f, self) self.canvas.draw() self.canvas.get_tk_widget().grid(row=1,column=0, columnspan=5, rowspan=5) def add_peak_selector(self, poss): self.poss = poss if self.curMenu != None: self.curMenu.destroy() self.selected = StringVar(self.controller) self.selected.set("Select Element") opts = ["Select Element"] + [p[0]+": "+str(p[1]) for p in poss] #Stupid tkinter workaround self.curMenu = OptionMenu(self,self.selected,*opts) self.curMenu.grid(row=2, column = 5) def back(self): self.controller.show_frame(ReviewFitPage) def submit(self): try: lowBound = float(self.lowerBound.get()) highBound = float(self.upperBound.get()) except ValueError: messagebox.showinfo("Error","Use numbers for the bounds please!") return None if lowBound > highBound: messagebox.showinfo("Error","Lower bound cannot be greater than upper bound!") return None if lowBound < self.energies[0] or highBound > self.energies[-1]: messagebox.showinfo("Error","Bounds must be within data bound") return None if self.selected.get() == "Select Peak": messagebox.showinfo("Error","Select a peak match!") return None #do integration #TODO: Infinite loop here i think i=0 while self.energies[i]<lowBound: i += 1 j=i while self.energies[j]<highBound: j += 1 #trapezoidal sum startEnergy = self.energies[i] endEnergy = self.energies[j] n = j-i+1 area = (self.energies[j] - self.energies[i]) / (2 * (j-i+1)) * (sum(self.cps[i:j+1])+sum(self.cps[i+1:j])) peak = [] element, loc = self.selected.get().split(": ") for i in self.poss: if i[0] == element and str(i[1]) == loc: peak = i self.controller.add_mi_peak(peak, area, startEnergy, endEnergy, n) self.controller.increment_peak_counter() self.curMenu.destroy()
def initInputs(self): graphFrame = Frame(self) graphFrame.pack(fill=BOTH, expand=True) fig = Figure(figsize=(1, 1), dpi=100) canvas = FigureCanvasTkAgg(fig, master=graphFrame) # A tk.DrawingArea. canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) canvas.draw() toolbar = NavigationToolbar2Tk(canvas, graphFrame) toolbar.update() inputsFrame = Frame(self) inputsFrame.grid_columnconfigure(1, weight=1) inputsFrame.grid_columnconfigure(3, weight=1) inputsFrame.pack(fill=X, padx=5, pady=5) # Loan Amount Label(inputsFrame, text="Loan Amount $", width=14).grid(row=0, column=0) e_loan = Entry(inputsFrame) e_loan.grid(row=0, column=1, stick="we", padx=(0, 5)) # Loan Term Label(inputsFrame, text="Term (Months)", width=14).grid(row=1, column=0) e_term = Entry(inputsFrame) e_term.grid(row=1, column=1, stick="we", padx=(0, 5)) # Loan Interest Label(inputsFrame, text="Monhtly Interest", width=14).grid(row=0, column=2) e_interest = Entry(inputsFrame) e_interest.grid(row=0, column=3, stick="we", padx=(0, 5)) # Increase Foresee Label(inputsFrame, text="Commodity Type", width=14).grid(row=1, column=2) e_commodity_options = ["", "MSFT", "AAPL", "IBM", "USDTRY=X", "EURTRY=X", "BTC-USD", "PETKM.IS", "TKC"] e_commodity_var = StringVar(inputsFrame) e_commodity_var.set(e_commodity_options[0]) e_commodity = OptionMenu(inputsFrame, e_commodity_var, *e_commodity_options) e_commodity.grid(row=1, column=3, stick="we", padx=(0, 5)) # Currently just printing values. predict_plot = fig.add_subplot(111) def calculate(): # Input variables. loan = int(e_loan.get()) interest = float(e_interest.get()) times = int(e_term.get()) commodity = e_commodity_var.get() debt = loan * interest * times / 100 + loan # YahooFinance historical data df = yf.download(commodity, period="10y", interval="1d") #---> Data Size dfreg = df.loc[:, ['Open', 'Close', 'Adj Close', 'Volume']] dfreg['HILO_PCT'] = (df['High'] - df['Low']) / df['Close'] * 100.0 dfreg['DELT_PCT'] = (df['Close'] - df['Open']) / df['Open'] * 100.0 dfreg.fillna(value=-99999, inplace=True) #Forecastout = Calculation of the time forecast_out = times * 30 # month times product days 30 so get the total time days dfreg['label'] = dfreg['Close'].shift(-forecast_out) #label stununa close vaerilirini atıyoruz forecastout dan alına sure kadar # Calculation of the lot liste2 = list(dfreg['Close'][-1:])# YF'den alınan son close datası alım olarak kabul edilir lot = loan / int(liste2[0]) # Separation x = dfreg.drop(columns='label') x = scale(x) # label dışındaki bütün verileri belli parametereye yerleştiriyor. y = dfreg.iloc[:, -1] # labeldaki tüm satırları al,en son sütunu al x_to_predict = x[-forecast_out:] # the last day we will guess # baştan al en son da ki tahmin ediceğimiz günü alma x = x[:-forecast_out] y = y[:-forecast_out] x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, random_state=0) regressor = LinearRegression() regressor.fit(x_train, y_train) # Training # Percentage of Accuracy accuracy = regressor.score(x_test, y_test) * 100 prediction_set = regressor.predict(x_to_predict) dfreg['Prediction'] = np.nan # Last date detection last_date = dfreg.iloc[-1].name lastDatetime = last_date.timestamp() one_day = 86400 # New date detection nexDatetime = lastDatetime + one_day for i in prediction_set: # Calculate elapsed time next_date = datetime.datetime.fromtimestamp(nexDatetime) nexDatetime += one_day dfreg.loc[next_date] = [np.nan for q in range(len(dfreg.columns) - 1)] + [i] # Last and First Predict detection firstPredict = list(dfreg['Prediction'][-forecast_out:-forecast_out + 1]) #----> ilk predict değerini listeden bulmka için -forecast:-forecast+1 yaparak predict forecastin ilk değerini buluruz. lastPredict = list(dfreg['Prediction'][-1:]) # Calculation of increase amount liste = lastPredict + firstPredict a = liste[0] b = liste[1] result = b - a increase = result / a * -1 * 100 #calculation of total profit total_profit = loan * increase - debt # Calculation of new list = lot X predict liste3 = list(dfreg['Prediction'][-forecast_out:]) liste3 = [i * lot for i in liste3] # Output labels Label(inputsFrame, text="Accuracy: {:.2f}%".format(accuracy), width=14).grid(row=2, column=0) Label(inputsFrame, text="Debt: ${:.2f}".format(debt), width=14).grid(row=2, column=1) Label(inputsFrame, text="Change: {:.2f}%".format(increase), width=14).grid(row=2, column=2) Label(inputsFrame, text="Total Profit : {:.2f}%".format(totalm), width=14).grid(row=2, column=3) # Plot Stuff predict_plot.clear() predict_plot.plot(liste3) predict_plot.plot([0, forecast_out], [loan, debt]) canvas.draw() # Button buttonsFrame = Frame(self) buttonsFrame.pack(fill=X, padx=5, pady=(0, 5)) b_calculate = Button(buttonsFrame, text="Calculate", command=calculate) b_calculate.pack(side=RIGHT)
class CategoryManager(Frame): """Category manager for the sticky notes.""" def __init__(self, master, app, **kwargs): Frame.__init__(self, master, **kwargs) self.columnconfigure(0, weight=1) self.app = app self.style = Style(self) self.style.theme_use("clam") self.im_plus = PhotoImage(file=IM_PLUS) self.im_moins = PhotoImage(file=IM_MOINS) # --- Default category self.frame_def_cat = Frame(self) self.default_category = StringVar(self.frame_def_cat, CONFIG.get("General", "default_category").capitalize()) Label(self.frame_def_cat, text=_("Default category ")).grid(row=0, column=0, sticky="e", padx=(4, 0)) self.categories = CONFIG.options("Categories") self.categories.sort() categories = [cat.capitalize() for cat in self.categories] self.def_cat_menu = OptionMenu(self.frame_def_cat, self.default_category, CONFIG.get("General", "default_category").capitalize(), *categories) optionmenu_patch(self.def_cat_menu, self.default_category) self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4) # --- Category colors, names ... self.frame_cat = Frame(self) self.colors = list(COLORS.keys()) self.colors.sort() self.images = [] for key in self.colors: self.images.append(PhotoImage(key, master=self, width=16, height=16)) fill(self.images[-1], COLORS[key]) self.cat_colors = {} self.cat_labels = {} self.cat_menus = {} self.cat_buttons = {} for i, cat in enumerate(self.categories): self.cat_labels[cat] = Label(self.frame_cat, text="%s" % cat.capitalize(), anchor='e') self.cat_labels[cat].grid(row=i + 2, column=0, sticky="ew", padx=2) self.cat_labels[cat].bind('<Double-Button-1>', self.change_name) self.cat_colors[cat] = StringVar(self) color = CONFIG.get("Categories", cat) self.cat_menus[cat] = OptionMenu(self.frame_cat, self.cat_colors[cat], INV_COLORS[color], *self.colors, command=lambda color, c=cat: self.change_menubutton_color(color, c), style="%s.TMenubutton" % cat) optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat]) self.style.configure("%s.TMenubutton" % cat, background=color) self.cat_menus[cat].grid(row=i + 2, column=1, sticky="w", padx=4, pady=4) self.cat_buttons[cat] = Button(self.frame_cat, image=self.im_moins, command=lambda c=cat: self.del_cat(c)) self.cat_buttons[cat].grid(row=i + 2, column=2, padx=4, pady=4) self.add_cat_button = Button(self.frame_cat, image=self.im_plus, command=self.add_cat) self.add_cat_button.grid(row=i + 3, column=0, pady=(0, 4)) if len(self.categories) == 1: self.cat_buttons[self.categories[0]].configure(state="disabled") # --- placement self.frame_def_cat.grid(row=0, column=0, sticky="eswn") Separator(self, orient="horizontal").grid(row=1, columnspan=3, pady=10, sticky="ew") self.frame_cat.grid(row=2, column=0, sticky="eswn") def change_name(self, event): def ok(event): cats = [l.cget('text').lower() for l in self.cat_labels.values()] cat = name.get().strip().lower() if cat and cat not in cats: label.configure(text=cat.capitalize()) if old_cat == self.default_category.get(): self.default_category.set(cat.capitalize()) self.update_def_cat_menu() name.destroy() label = event.widget old_cat = label.cget('text') name = Entry(self, justify='center') name.insert(0, label.cget('text')) name.place(in_=label, relx=0, rely=0, anchor='nw', relwidth=1, relheight=1) name.bind('<FocusOut>', lambda e: name.destroy()) name.bind('<Escape>', lambda e: name.destroy()) name.bind('<Return>', ok) name.selection_range(0, 'end') name.focus_set() def get_color(self, category): return self.cat_colors[category].get() def get_name(self, category): return self.cat_labels[category].cget('text').lower() def change_menubutton_color(self, color, cat): """ change the color of the menubutton of the category cat when its default color is changed """ self.style.configure("%s.TMenubutton" % cat, background=COLORS[color]) def del_cat(self, category): rep = askyesnocancel(_("Question"), _("Do you want to delete all notes belonging to \ the category %(category)s? If you answer 'No', the category will be deleted but \ the notes will belong to the default category. Be careful, the change will take \ effect immediately and cannot be undone." % {"category": category})) if rep is not None: del(self.cat_colors[category]) self.cat_buttons[category].grid_forget() del(self.cat_buttons[category]) self.cat_labels[category].grid_forget() cat = self.cat_labels[category].cget('text') del(self.cat_labels[category]) self.cat_menus[category].grid_forget() del(self.cat_menus[category]) self.categories.remove(category) CONFIG.remove_option("Categories", category) if self.default_category.get() == cat: default = list(self.cat_labels.values())[0].cget('text') self.default_category.set(default) CONFIG.set("General", "default_category", default.lower()) self.update_def_cat_menu() if len(self.categories) == 1: self.cat_buttons[self.categories[0]].configure(state="disabled") if rep: self.app.delete_cat(category) self.app.update_notes() self.app.update_menu() save_config() def update_def_cat_menu(self): self.def_cat_menu.destroy() categories = [l.cget('text') for l in self.cat_labels.values()] self.def_cat_menu = OptionMenu(self.frame_def_cat, self.default_category, None, *categories) optionmenu_patch(self.def_cat_menu, self.default_category) self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4) def add_cat(self): top = Toplevel(self) top.transient(self) top.grab_set() top.resizable(False, False) top.title(_("New Category")) def valide(event=None): cats = [l.cget('text').lower() for l in self.cat_labels.values()] cat = name.get().strip().lower() if cat and cat not in cats: i = self.add_cat_button.grid_info()['row'] self.add_cat_button.grid_configure(row=i + 1) self.cat_labels[cat] = Label(self.frame_cat, text="%s " % cat.capitalize()) self.cat_labels[cat].grid(row=i, column=0, sticky="e") self.cat_colors[cat] = StringVar(self, _("Yellow")) self.cat_menus[cat] = OptionMenu(self.frame_cat, self.cat_colors[cat], _("Yellow"), *self.colors, command=lambda color, c=cat: self.change_menubutton_color(color, c), style="%s.TMenubutton" % cat) self.style.configure("%s.TMenubutton" % cat, background=COLORS[_("Yellow")]) optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat]) self.cat_menus[cat].grid(row=i, column=1, padx=4, pady=4) self.cat_buttons[cat] = Button(self.frame_cat, image=self.im_moins, command=lambda c=cat: self.del_cat(c)) self.cat_buttons[cat].grid(row=i, column=2, padx=4, pady=4) self.cat_buttons[self.categories[0]].configure(state="normal") self.categories.append(cat) self.categories.sort() self.update_def_cat_menu() top.destroy() name = Entry(top, justify="center") name.grid(row=0, column=0, columnspan=2, sticky="ew") name.bind("<Return>", valide) name.focus_set() Button(top, text="Ok", command=valide).grid(row=1, column=0, sticky="nswe") Button(top, text=_("Cancel"), command=top.destroy).grid(row=1, column=1, sticky="nswe")
def getProgrammerHardwareAdapter(port): for adapter in adapters: if adapter.canProgram(port): return adapter(port) return None com_port_status_sv = StringVar(r) com_port_status_l = Label(r, textvariable=com_port_status_sv) com_port_status_l.grid(column=1, row=0, sticky=W + E, padx=10, pady=8) com_port_sv = StringVar(r) com_port_sv.set("") select_port_om = OptionMenu(r, com_port_sv, ()) select_port_om.grid(column=0, row=0, sticky=W + E, padx=10, pady=8) tinyfpga_adapters = dict() tinyfpga_ports = [] def update_serial_port_list_task(): global tinyfpga_ports global program_in_progress global tinyfpga_adapters if not program_in_progress: new_tinyfpga_adapters = dict( (adapter.displayName(), adapter) for adapter in [getProgrammerHardwareAdapter(port) for port in comports()] if adapter is not None)
class GUI_setup(Frame): def __init__(self, kernel, master=None): Frame.__init__(self, master) self.kernel = kernel self.grid() self.master.title("YuMi experiment") self.client_tuple = None self.master.protocol("WM_DELETE_WINDOW", self.kernel.close_setup) #self.master.geometry("100x100+500+100") config = self.kernel.read_config() frame_session_type = Frame(self.master, relief=GROOVE, borderwidth=2) frame_participant = Frame(self.master, relief=GROOVE, borderwidth=2) frame_data_bases = Frame(self.master, relief=GROOVE, borderwidth=2) frame_server = Frame(self.master, relief=GROOVE, borderwidth=2) # Session type self.rbType = StringVar(self.master) lbl1 = Label(frame_session_type, text="Session type") rb1 = Radiobutton(frame_session_type, text="Hololens", variable=self.rbType, value="hololens", command=self.type) rb2 = Radiobutton(frame_session_type, text="Monitor", variable=self.rbType, value="monitor", command=self.type) rb3 = Radiobutton(frame_session_type, text="Dialogue", variable=self.rbType, value="dialogue", command=self.type) rb4 = Radiobutton(frame_session_type, text="Projector", variable=self.rbType, value="projector", command=self.type) self.rbType.set("hololens") rb1.select() rb2.deselect() rb3.deselect() rb4.deselect() lbl1.grid(row=0, column=0, sticky=W+N) rb1.grid(row=1, column=0, sticky=W+N) rb2.grid(row=2, column=0, sticky=W+N) rb3.grid(row=3, column=0, sticky=W+N) rb4.grid(row=4, column=0, sticky=W+N) # Data base self.data_base_path = config["data_base_path"] try: listdir(self.data_base_path) except FileNotFoundError: self.data_base_path = dirname(__file__) data_files = [f for f in listdir(self.data_base_path) if isfile(join(self.data_base_path, f))] data_files = [files for files in data_files if ".csv" in files] self.data_file = StringVar(master) if len(data_files) == 0: data_files.append("No data found") self.data_file.set(data_files[0]) lbl2 = Label(frame_data_bases, text="Data base") btn_browse = Button(frame_data_bases, text="Browse", command=self.kernel.browse_db) self.db_drop = OptionMenu(frame_data_bases, self.data_file, *data_files, command=self.kernel.set_db) self.data_base_file = join(self.data_base_path, self.data_file.get()) lbl_db1 = Label(frame_data_bases, text="Found in:") lbl_db2 = Label(frame_data_bases, text="Choose:") lbl_text = self.data_base_path if len(lbl_text) > 30: lbl_text = "..." + lbl_text[-30:] self.lbl_db3 = Label(frame_data_bases, text=lbl_text) lbl2.grid(row=0, column=0, columnspan=1, sticky=W+N) lbl_db2.grid(row=1, column=0, columnspan=1, sticky=W+N) self.db_drop.grid(row=1, column=1, columnspan=3, sticky=E+N) lbl_db1.grid(row=2, column=0, columnspan=1, sticky=W+N) self.lbl_db3.grid(row=2, column=1, columnspan=3, sticky=W+N) btn_browse.grid(row=3, column=3, sticky=E+N) # Participant self.write_to_path = config["write_to_path"] try: listdir(self.write_to_path) except FileNotFoundError: self.write_to_path = dirname(__file__) part_dirs = [f for f in listdir(self.write_to_path) if isdir(join(self.write_to_path, f))] part_dirs = [dirs for dirs in part_dirs if "participant" in dirs] parts = [" ".join(part.split("_")[0:2]) for part in part_dirs] self.participant = StringVar() self.participant.set("New participant") # default value parts = [self.participant.get()] + parts lbl_part = Label(frame_participant, text="Name:") self.part_entry = Entry(frame_participant, textvariable=self.participant) lbl3 = Label(frame_participant, text="Participant") lbl_text = self.write_to_path if len(lbl_text) > 10: lbl_text = "..." + lbl_text[-10:] self.lbl4 = Label(frame_participant, text=lbl_text) lbl5 = Label(frame_participant, text="Save to:") self.dropdown_participant = OptionMenu(frame_participant, self.participant, *parts) btn_browse2 = Button(frame_participant, text="Browse", command=self.kernel.browse_part) lbl_part.grid(row=1, column=0, sticky=W+N) self.part_entry.grid(row=1, column=1, sticky=W+N) lbl3.grid(row=0, column=0, sticky=W+N) self.dropdown_participant.grid(row=2, column=1, columnspan=2, sticky=W+N+E) lbl5.grid(row=3, column=0, columnspan=1, sticky=W+N) self.lbl4.grid(row=3, column=1, sticky=W+N) btn_browse2.grid(row=4, column=1, sticky=E+N) # Server self.addr = StringVar(master) self.addrs = config["server_adrs"].split(";") self.addr.set(self.addrs[0]) self.port = StringVar(master) self.ports = config["server_ports"].split(";") self.port.set(self.ports[0]) lbl6 = Label(frame_server, text="Connect to server") lbl7 = Label(frame_server, text="Server address:") lbl8 = Label(frame_server, text="Server port:") self.rbServer1 = StringVar(self.master) rb4 = Radiobutton(frame_server, text="", variable=self.rbServer1, value="entry", command=self.server1) rb5 = Radiobutton(frame_server, text="", variable=self.rbServer1, value="list", command=self.server1) self.rbServer1.set("entry") rb4.select() rb5.deselect() self.adr_entry = Entry(frame_server, textvariable=self.addr) self.adr_drop = OptionMenu(frame_server, self.addr, *self.addrs) self.adr_drop['state'] = 'disabled' self.rbServer2 = StringVar(self.master) rb6 = Radiobutton(frame_server, text="", variable=self.rbServer2, value="entry", command=self.server2) rb7 = Radiobutton(frame_server, text="", variable=self.rbServer2, value="list", command=self.server2) rb6.select() rb7.deselect() self.rbServer2.set("entry") self.port_entry = Entry(frame_server, textvariable=self.port) self.port_drop = OptionMenu(frame_server, self.port, *self.ports) self.port_drop['state'] = 'disabled' lbl8 = Label(frame_server, text="Status:") lbl_text = "Not connected" if self.kernel.client_tuple: lbl_text = "Connected to {}".format(self.kernel.client_tuple[0].host) self.lbl9 = Label(frame_server, text=lbl_text) btn_connect = Button(frame_server, text="Connect", command=self.kernel.connect) lbl6.grid(row=0, column=0, sticky=W+E+N+S) lbl7.grid(row=1, column=0, rowspan=2, sticky=W) rb4.grid(row=1, column=2, columnspan=1, rowspan=1, sticky=W) self.adr_entry.grid(row=1, column=3, columnspan=1, rowspan=1, sticky=W+E+N+S) rb5.grid(row=2, column=2, columnspan=1, rowspan=1, sticky=W) self.adr_drop.grid(row=2, column=3, columnspan=1, rowspan=1, sticky=W+E+N+S) lbl8.grid(row=3, column=0, rowspan=2, sticky=W) rb6.grid(row=3, column=2, columnspan=1, rowspan=1, sticky=W) self.port_entry.grid(row=3, column=3, columnspan=1, rowspan=1, sticky=W+E+N+S) rb7.grid(row=4, column=2, columnspan=1, rowspan=1, sticky=W) self.port_drop.grid(row=4, column=3, columnspan=1, rowspan=1, sticky=W+E+N+S) lbl8.grid(row=5, column=0, columnspan=1, rowspan=1, sticky=W) self.lbl9.grid(row=5, column=3, columnspan=1, rowspan=1, sticky=W) btn_connect.grid(row=6, column=3, columnspan=1, rowspan=1, sticky=W) # Layout btn_launch = Button(self.master, text="Launch", command=self.kernel.launch) frame_session_type.grid(row=0,column=0, columnspan=1, rowspan=1, sticky=W+E+N+S) frame_data_bases.grid(row=1, column=1, columnspan=1, rowspan=1, sticky=W+E+N+S) frame_participant.grid(row=1, column=0, columnspan=1, rowspan=1, sticky=W+E+N+S) frame_server.grid(row=0, column=1, columnspan=1, rowspan=1, sticky=W+E+N+S) btn_launch.grid(row=2, column=1, sticky=E) def type(self): pass def server1(self): if self.rbServer1.get() == "entry": self.adr_entry['state'] = 'normal' self.adr_drop['state'] = 'disabled' else: self.adr_entry['state'] = 'disabled' self.adr_drop['state'] = 'normal' def server2(self): if self.rbServer2.get() == "entry": self.port_entry['state'] = 'normal' self.port_drop['state'] = 'disabled' else: self.port_entry['state'] = 'disabled' self.port_drop['state'] = 'normal'
class Config(Frame): data = None def __init__(self, parent=None): super().__init__(parent) parent.bind('<Return>', self.on_accept_button_click) self.pack(side=LEFT, fill=BOTH, expand=True) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) style = AppStyle() style.configure("SELF.TLabel", width=15) style.configure("SELF.TEntry", width=200, padding=5) style.configure("SELF.TMenubutton", width=200, padding=5) # Tab container. notebook = Notebook(self) # Main tab content main = Frame(notebook) main.columnconfigure(1, weight=1) screen_label = Label(main, text="Screen", style="SELF.TLabel") screen_label.grid(row=0, column=0, padx=[10, 0], pady=[10, 0], sticky=W) self.screen_entry = Entry(main, style="SELF.TEntry") self.screen_entry.grid(row=0, column=1, padx=[0, 10], pady=[10, 0], sticky=W + E) width_label = Label(main, text="Width percent", style="SELF.TLabel") width_label.grid(row=1, column=0, padx=[10, 0], pady=[5, 0], sticky=W) self.width_entry = Entry(main, style="SELF.TEntry") self.width_entry.grid(row=1, column=1, padx=[0, 10], pady=[5, 0], sticky=W + E) height_label = Label(main, text="Height percent", style="SELF.TLabel") height_label.grid(row=2, column=0, padx=[10, 0], pady=[5, 0], sticky=W) self.height_entry = Entry(main, style="SELF.TEntry") self.height_entry.grid(row=2, column=1, padx=[0, 10], pady=[5, 0], sticky=W + E) camera_type_label = Label(main, text="Camera type", style="SELF.TLabel") camera_type_label.grid(row=3, column=0, padx=[10, 0], pady=[5, 10], sticky=W) self.camera_type_entry = Entry(main, style="SELF.TEntry") self.camera_type_entry.grid(row=3, column=1, padx=[0, 10], pady=[5, 10], sticky=W + E) # Frames tab content. frames = Frame(notebook) frames.columnconfigure(1, weight=1) frame_interval_label = Label(frames, text="Frame interval", style="SELF.TLabel") frame_interval_label.grid(row=0, column=0, padx=[10, 0], pady=[10, 0], sticky=W) self.frame_interval_entry = Entry(frames, style="SELF.TEntry") self.frame_interval_entry.grid(row=0, column=1, padx=[0, 10], pady=[10, 0], sticky=W + E) frame_rate_label = Label(frames, text="Frame rate", style="SELF.TLabel") frame_rate_label.grid(row=1, column=0, padx=[10, 0], pady=[10, 0], sticky=W) self.frame_rate_entry = Entry(frames, style="SELF.TEntry") self.frame_rate_entry.grid(row=1, column=1, padx=[0, 10], pady=[10, 0], sticky=W + E) frame_count_label = Label(frames, text="Frame count", style="SELF.TLabel") frame_count_label.grid(row=2, column=0, padx=[10, 0], pady=[10, 0], sticky=W) self.frame_count_entry = Entry(frames, style="SELF.TEntry") self.frame_count_entry.grid(row=2, column=1, padx=[0, 10], pady=[10, 0], sticky=W + E) # Cameras tab content. cameras = Frame(notebook) cameras.columnconfigure(1, weight=1) camera_label = Label(cameras, text="Cameras", style="SELF.TLabel") camera_label.grid(row=0, column=0, padx=[10, 0], pady=[10, 0], sticky=W) self.selected_camera_var = StringVar(self) self.selected_camera_var.trace('w', self.on_camera_option_select) self.cameras_options = OptionMenu(cameras, self.selected_camera_var, style="SELF.TMenubutton") self.cameras_options.grid(row=0, column=1, padx=[0, 10], pady=[10, 0], sticky=E) add_cam_button = Button(cameras, text="Add", width=5, command=self.on_add_cam_button_click) add_cam_button.grid(row=0, column=2, padx=[0, 10], pady=[10, 0], sticky=E) delete_cam_button = Button(cameras, text="Delete", width=5, command=self.on_delete_cam_button_click) delete_cam_button.grid(row=0, column=3, padx=[0, 10], pady=[10, 0], sticky=E) self.edit_cam_entry = Entry(cameras, style="SELF.TEntry") self.edit_cam_entry.grid(row=1, column=0, columnspan=3, padx=10, pady=[5, 0], sticky=W + E) edit_cam_button = Button(cameras, text="Edit", width=5, command=self.on_edit_cam_button_click) edit_cam_button.grid(row=1, column=2, columnspan=2, padx=[0, 10], pady=[5, 0], sticky=E) # Add the tabs. notebook.add(main, text="Main") notebook.add(frames, text="Frames") notebook.add(cameras, text="Cameras") notebook.grid(row=0, column=0, columnspan=4, padx=10, pady=10, sticky=W + E) accept_button = Button(self, text="Accept") accept_button.grid(row=1, column=1, padx=[0, 10], sticky=N + E) accept_button.bind("<Button-1>", self.on_accept_button_click) default_button = Button(self, text="Default") default_button.grid(row=1, column=2, padx=[0, 10], sticky=N + E) default_button.bind("<Button-1>", self.on_default_button_click) cancel_button = Button(self, text="Cancel") cancel_button.grid(row=1, column=3, padx=[0, 10], sticky=N + E) cancel_button.bind("<Button-1>", self.on_cancel_button_click) # Load configuration. self.load_config() def on_camera_option_select(self, *args): if self.data is not None: self.edit_cam_entry.delete(0, END) self.edit_cam_entry.insert(0, self.data["cameras"][self.selected_camera_var.get()]) def on_add_cam_button_click(self): # Get the no of cameras. index = len(self.data["cameras"]) # Add the camera to the data dictionary. self.data["cameras"][str(index)] = self.edit_cam_entry.get() # Update camera select box. self.clear_cameras() self.add_cameras(index) def on_delete_cam_button_click(self): size = len(self.data["cameras"]) if size > 1: index = size - 1 self.data["cameras"].pop(str(index)) # Update cameras self.clear_cameras() self.add_cameras(index - 1) else: messagebox.showinfo("Cannot Delete Camera", "There must be at least one camera on the list.") def on_edit_cam_button_click(self): index = self.selected_camera_var.get() self.data["cameras"][str(index)] = self.edit_cam_entry.get() # Update camera select box. self.clear_cameras() self.add_cameras(index) def on_accept_button_click(self, _): self.save_config() def on_default_button_click(self, _): res = messagebox.askyesno("Confirm Settings Reset", "Are you sure you want to reset settings to default?") if res is True: reset_default() self.reset_form() self.load_config() def on_cancel_button_click(self, _): self.master.destroy() def reset_form(self): """Clear the current form content""" self.screen_entry.delete(0, END) self.width_entry.delete(0, END) self.height_entry.delete(0, END) self.camera_type_entry.delete(0, END) self.frame_interval_entry.delete(0, END) self.frame_rate_entry.delete(0, END) self.frame_count_entry.delete(0, END) self.clear_cameras() def load_config(self): data = read_settings() # Load main section. self.screen_entry.insert(0, data["main"]["screen"]) self.width_entry.insert(0, data["main"]["width_percent"]) self.height_entry.insert(0, data["main"]["height_percent"]) self.camera_type_entry.insert(0, data["main"]["type_camera"]) # Load frames section self.frame_interval_entry.insert(0, data["frames"]["frame_interval"]) self.frame_rate_entry.insert(0, data["frames"]["frame_rate"]) self.frame_count_entry.insert(0, data["frames"]["frame_count"]) # Set the class data field to the JSON dict. self.data = data self.add_cameras(0) def clear_cameras(self): self.cameras_options['menu'].delete(0, 'end') def add_cameras(self, selection: int): cams = [] # Load cameras section for cam in self.data["cameras"]: cams.append(cam) # Sort list cams = sorted(cams) # Append list to options. for cam in cams: self.cameras_options['menu'].add_command(label=cam, command=_setit(self.selected_camera_var, cam)) # Set selected item to the 0 self.selected_camera_var.set(selection) def save_config(self): data = self.data # Set main section. data["main"]["screen"] = self.screen_entry.get() data["main"]["width_percent"] = self.width_entry.get() data["main"]["height_percent"] = self.height_entry.get() data["main"]["type_camera"] = self.camera_type_entry.get() # Set frames section. data["frames"]["frame_interval"] = self.frame_interval_entry.get() data["frames"]["frame_rate"] = self.frame_rate_entry.get() data["frames"]["frame_count"] = self.frame_count_entry.get() # Save JSON data into file. if not write_settings(data): messagebox.showerror(title="An Error Occurred!", message="Couldn't save the changes.") else: self.master.destroy()
class Dicom(Module): def __init__(self, app): info(' - initializing module: Dicom') self.app = app if LIBS_INSTALLED: # grid load button self.frame_holder = Frame(self.app.LEFT) #, pady=7) self.frame_holder.grid(row=2) self.frame = Frame(self.frame_holder) self.frame.pack(expand=True) self.method = StringVar(self.app) self.mode = None self.reader = None # zoom buttons self.zbframe = Frame(self.app.LEFT) self.zbframe.grid(row=6, column=0) # zoom frame (contains our tracing canvas) self.zframe = ZoomFrame(self.app.RIGHT, 1.3, app) # zoom in, zoom out, reset zoom buttons #self.header = Header(self.zbframe, text="Zoom") self.zoomResetBtn = Button(self.zbframe, text='⊜', command=self.zoomReset, width=1.5, style="symbol.TButton", takefocus=0) #, pady=7 ) self.zoomInBtn = Button(self.zbframe, text='⊕', command=self.zoomIn, width=1.5, style="symbol.TButton", takefocus=0) self.zoomOutBtn = Button(self.zbframe, text='⊝', command=self.zoomOut, width=1.5, style="symbol.TButton", takefocus=0) # reset zoom keyboard shortcut if util.get_platform() == 'Linux': self.app.bind('<Control-0>', self.zoomReset) else: self.app.bind('<Command-0>', self.zoomReset) self.reset() self.grid() def zoomReset(self, fromButton=False): ''' reset zoom frame canvas and rebind it ''' if self.isLoaded(): # creates a new canvas object and we redraw everything to it self.zframe.resetCanvas() # self.zframe.canvas.bind('<Button-1>', self.app.onClickZoom ) # self.zframe.canvas.bind('<ButtonRelease-1>', self.app.onRelease ) # self.zframe.canvas.bind('<Motion>', self.app.onMotion ) # we want to go here only after a button press if fromButton: self.app.framesUpdate() def zoomIn(self): self.zframe.zoomIn() def zoomOut(self): self.zframe.zoomOut() def update(self, _frame=None): ''' change the image on the zoom frame ''' if self.reader and self.reader.loaded: self.zframe.setImage(self.reader.getFrame(_frame or self.app.frame)) def load(self, event=None): ''' brings a dicom file into memory if it exists ''' if LIBS_INSTALLED: if self.reader and not self.reader.loaded: self.reader.load() self.app.frame = 1 self.update() self.loadBtn['state'] = 'disabled' def chooseMethod(self, event=None): if self.mode: cls = LABEL_TO_READER[self.mode][self.method.get()] if self.mode == 'dicom': dcm = self.app.Data.checkFileLevel('.dicom') if dcm: if cls == DicomPNGReader and self.app.Data.getFileLevel( 'processed'): self.reader = cls(dcm, self.app.Data.path) else: self.reader = cls(dcm) else: self.reader = None elif self.mode == 'ult': ult = self.app.Data.checkFileLevel('.ult') meta = self.app.Data.checkFileLevel('US.txt') if ult and meta: self.reader = cls(ult, meta) else: self.reader = None self.zframe.resetImageDimensions() if not self.reader: self.loadBtn['state'] = 'disabled' elif self.reader.loaded: self.loadBtn['state'] = 'disabled' self.update() else: self.loadBtn['state'] = 'normal' def isLoaded(self): return self.reader and self.reader.loaded def getFrames(self, framenums): return [self.reader.getFrame(int(x)) for x in framenums] def getFrameTimes(self): if self.reader: return self.reader.getFrameTimes() elif self.mode == 'dicom': rd = DicomReader( self.app.Data.unrelativize( self.app.Data.getFileLevel('.dicom'))) return rd.getFrameTimes() elif self.mode == 'ult': rd = ULTScanLineReader( self.app.Data.unrelativize(self.app.Data.getFileLevel('.ult')), self.app.Data.unrelativize( self.app.Data.getFileLevel('US.txt'))) return rd.getFrameTimes() else: return [0] def reset(self): ''' new files should default to not showing dicom unless it has already been processed ''' # hide frame navigation widgets # self.grid_remove() self.zframe.shown = False self.zframe.setImage(None) self.frame.destroy() self.frame = Frame(self.frame_holder) self.frame.pack(expand=True) self.reader = None if self.app.Data.getFileLevel('.dicom'): self.mode = 'dicom' elif self.app.Data.getFileLevel('.ult'): self.mode = 'ult' else: self.mode = None self.method.set('') options = [x.label for x in READERS[self.mode]] or ['[no ultrasound]'] self.methodMenu = OptionMenu(self.frame, self.method, '---', *options, command=self.chooseMethod) self.methodMenu.grid(row=0) self.loadBtn = Button(self.frame, text='Load frames', command=self.load, takefocus=0, state='disabled') self.loadBtn.grid(row=1) if len(READERS[self.mode]) == 1: self.method.set(options[0]) self.chooseMethod() def grid(self): ''' Grid frame navigation, zoom reset, and Control (Undo/Redo) widgets ''' self.app.framesHeader.grid(row=0) self.app.framesPrevBtn.grid(row=0, column=0) self.app.framesEntryText.grid(row=0, column=1) self.app.framesEntryBtn.grid(row=0, column=2) self.app.framesNextBtn.grid(row=0, column=3) #self.header.grid(row=0, column=0, columnspan=5) self.zoomInBtn.grid(row=0, column=3) self.zoomResetBtn.grid(row=0, column=2) self.zoomOutBtn.grid(row=0, column=1) self.app.Control.grid() def grid_remove(self): ''' Remove widgets from grid ''' self.app.framesHeader.grid_remove() self.app.framesPrevBtn.grid_remove() self.app.framesEntryText.grid_remove() self.app.framesEntryBtn.grid_remove() self.app.framesNextBtn.grid_remove() self.zoomInBtn.grid_remove() self.zoomResetBtn.grid_remove() self.zoomOutBtn.grid_remove() self.app.Control.grid_remove()
class Main(Frame): REMOTE_UPDATE_URL = "http://www.aiquimist.com/update/parameters.json" data = None shouldUpdate = False snapshot_dir = "snapshots" canvas = None capture = None photo = None delay = 15 def __init__(self, parent=None): super().__init__(parent) self.pack(side=LEFT, fill=BOTH, expand=True) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) self.bind("<configure>", self.on_window_resize()) self.master.protocol("WM_DELETE_WINDOW", self.on_window_close) style = AppStyle() # Read application settings. self.data = read_settings() # Top frame styles. style.configure("TOP.TFrame") # Bottom frame styles. style.configure("BOT.TFrame") # Button styles. style.configure("TOP.TMenubutton", padding=13) top_frame = Frame(self, padding=10, style="TOP.TFrame") top_frame.grid(row=0, column=0, sticky="ew") top_frame.columnconfigure(0, weight=1) top_frame.columnconfigure(7, weight=1) cams_list = self.get_cams_list() self.selected_camera_var = StringVar() self.selected_camera_var.trace('w', self.on_camera_option_select) self.cameras_option = OptionMenu(top_frame, self.selected_camera_var, None, *cams_list, command=self.on_camera_option_select, style="TOP.TMenubutton") self.cameras_option.grid(row=0, column=1, padx=[0, 10]) self._biometry_image = PhotoImage(file="resources/biometrical.gif") biometry_button = Button(top_frame, image=self._biometry_image, compound=LEFT, text="Recognize", command=self.on_recognize_button_click) biometry_button.grid(row=0, column=2, padx=[0, 10]) self._open_image = PhotoImage(file="resources/folder_open.gif") open_button = Button(top_frame, image=self._open_image, compound=LEFT, text="Open", command=self.on_open_button_click) open_button.grid(row=0, column=3, padx=[0, 10]) self._config_image = PhotoImage(file="resources/config.gif") config_button = Button(top_frame, image=self._config_image, compound=LEFT, text="Config", command=self.on_config_button_click) config_button.grid(row=0, column=4, padx=[0, 10]) self._update_image = PhotoImage(file="resources/download.gif") update_button = Button(top_frame, image=self._update_image, compound=LEFT, text="Update", command=self.on_update_button_click) update_button.grid(row=0, column=5, padx=[0, 10]) self._close_image = PhotoImage(file="resources/close.gif") close_button = Button(top_frame, image=self._close_image, compound=LEFT, text="Close", command=self.on_window_close) close_button.grid(row=0, column=6, padx=[0, 10]) bottom_frame = Frame(self, padding=10, style="BOT.TFrame", relief=SUNKEN) bottom_frame.grid(row=1, column=0, padx=10, pady=[0, 10], sticky="nsew") self.canvas = Canvas(bottom_frame, bg="black") self.canvas.pack(fill=BOTH, expand=True) # Set the default camera. self.selected_camera_var.set(cams_list[0]) def get_cams_list(self): cams = [] # Load cameras section for cam in self.data["cameras"]: cams.append(cam) # Return the sorted list return sorted(cams) def on_window_close(self): self.shouldUpdate = False self.master.quit() def on_window_resize(self): if self.canvas is not None: self.canvas.configure(relx=0.5, rely=0.5, anchor=CENTER) def on_camera_option_select(self, *args): # Delete the existing capture object. if self.capture is not None: del self.capture source = self.data["cameras"][self.selected_camera_var.get()] self.init_video(source) def init_video(self, source): # Convert source to integer if numeric. if source.isnumeric(): source = int(source) try: self.capture = VideoCapture(video_source=source, snapshot_dir=self.snapshot_dir) except ValueError as e: msg = "Couldn't open the stream: {0}".format(str(e)) logging.critical(msg) messagebox.showerror("Error Opening Stream", msg) self.canvas.delete("all") return self.shouldUpdate = True while self.shouldUpdate: self.master.after(self.delay, self.update_canvas()) def update_canvas(self): if self.capture is not None: # Force update values. self.canvas.update() can_width = self.canvas.winfo_width() can_height = self.canvas.winfo_height() # Get a frame from the video source. try: ret, frame = self.capture.get_frame(can_width, can_height) if ret: self.photo = PhotoImage(image=fromarray(frame)) self.canvas.create_image(can_width / 2, can_height / 2, image=self.photo) except Exception as e: self.shouldUpdate = False def on_recognize_button_click(self): ret = self.capture.take_snapshot() if ret: messagebox.showinfo("Image Capture", "Snapshot saved!") else: messagebox.showerror("Image Capture", "Failed to save snapshot.") def on_open_button_click(self): open_file(self.snapshot_dir) def on_config_button_click(self): child = Toplevel(self) child.title("Config") child.geometry("400x235") center_window(child) child.transient(self) child.resizable(False, False) child.grab_set() Config(child) self.wait_window(child) # Read the new settings. self.data = read_settings() def on_update_button_click(self): try: opener = URLopener() opener.retrieve(self.REMOTE_UPDATE_URL, "resources/parameters.json") # Read the new settings. self.data = read_settings() messagebox.showinfo( "Settings Update", "Settings successfully updated from the server.") except Exception as e: logging.critical( "Couldn't open the remote settings file: {0}".format(str(e))) messagebox.showerror("Couldn't Update Settings", "Couldn't open the remote settings file.")
class TimelapseGUI(): # CLASS CONSTANTS READY_TEXT = "Ready!" ICON_NAME = "assets/favicon.png" MIN_WIDTH = 500 MIN_HEIGHT = 300 CHOICES = [ 'Choose Speed', '2x', '5x', '10x', '20x', '30x', '50x', '100x', '200x', '300x', '500x', '1000x', ] SUPPORTED_FORMATS = [ '.mp4', '.webm', '.mpg', '.avi', '.mov', '.m4v', '.flv', '.mkv' ] def __init__(self): """ __init__ Initializes the GUI elements """ # variables self.files = None self.file_status = None self.var_open_files = None self.progress = None # Root Window Properties self.root = Tk() self.root.title("Timelapse Creator") self.root.minsize(self.MIN_WIDTH, self.MIN_HEIGHT) # This part is to make sure that the program runs with or without n icon file. try: if os.path.exists(self.ICON_NAME): self.icon = PhotoImage(file=self.ICON_NAME) self.root.iconphoto(False, self.icon) elif os.path.exists(os.path.split(self.ICON_NAME)[-1]): self.icon = PhotoImage(file=os.path.split(self.ICON_NAME)[-1]) self.root.iconphoto(False, self.icon) except Exception as e: print(f"Could not load Icon due to Error: {e}") # Buttons and Widgets self.config_frames() self.config_buttons() self.config_progress_bar() self.config_label() def config_frames(self): """ config_frames Set up the different sections of the GUI window """ # BUTTON SPACE self.buttons_frame = Frame(self.root) self.buttons_frame.grid(row=0, column=0, columnspan=3, padx=10, pady=10, sticky=E + W) # PROGRESS BAR SPACE self.progress_frame = Frame(self.root) self.progress_frame.grid(row=1, column=0, columnspan=3, padx=10, pady=10, sticky=E + W) # Configure how many rows and columns are there in and progress_frame self.root.columnconfigure(0, weight=1) self.root.rowconfigure(1, weight=1) self.progress_frame.columnconfigure(0, weight=1) self.progress_frame.rowconfigure(0, weight=1) def config_buttons(self): """ config_buttons Define the interactive Buttons used for the GUI App """ # Open File Browser Button self.btn_open_files = Button(self.buttons_frame, command=self.browseFiles, text='Select Videos') self.btn_open_files.grid(row=0, column=0, padx=(10), pady=10) # Dropdown Selector button self.var_open_files = StringVar(self.buttons_frame) self.dropdown_button = OptionMenu(self.buttons_frame, self.var_open_files, *self.CHOICES) self.dropdown_button.grid(row=0, column=1, padx=(10), pady=10) # Convert Button self.btn_convert = Button(self.buttons_frame, text='Convert', command=self.convert_video) self.btn_convert.grid(row=0, column=2, padx=(10), pady=10) def config_progress_bar(self): """ config_progress_bar Configure the Progress bar """ self.progress = Progressbar(self.progress_frame, orient=HORIZONTAL, length=100, mode='determinate') self.progress.grid(row=1, column=0, sticky=E + W) def config_label(self): """ config_label Add the Dynamic labels for progress tracking """ self.file_status = Label(self.progress_frame, text=self.READY_TEXT) self.file_status.grid(row=0, column=0, padx=(10), pady=10) self.file_status_percent = Label(self.progress_frame, text="0%") self.file_status_percent.grid(row=1, column=0, padx=(0), pady=0) def run(self): """ run Run the GUI Loop. """ self.root.mainloop() def file_format_generator(self, formats: list): """ file_format_generator Generates the required file format - helper function Takes a List of strings as input, adds their upper case versions as well Converts them to a space separated string, and returns the same Args: formats (list): comma separated strings of file extensions in lower case Returns: string: space separated file extensions along with corresponding upper case format """ formats = formats + [value.upper() for value in formats] return " ".join(formats) def browseFiles(self): """ browseFiles Creates the File Selector dialogbox Returns: boolean: True if valid file is selected, False if invalid """ self.files = filedialog.askopenfilenames( # initialdir="/media/Data/Downloads/", title="Videos", filetypes=(("Video Files", self.file_format_generator(self.SUPPORTED_FORMATS)), )) # Check file validity valid = bulk_validate_video(self.files) if not valid: messagebox.showerror( title="Invalid File", message="The File that you entered is invalid. Please retry!") return False return True def convert_video(self): """ convert_video Main video converter function Uses OpenCV to read and write the video While skipping frames based on the given input Returns: boolean: Returns True or False based on success or failure """ # Warning Box for if proper files have not been selected if not self.files: messagebox.showwarning( title="File Not Selected", message= "You have not selected any file. Please Click on \"Select Videos\"" ) return False # Extract the multiplier number fps_multiplier = self.var_open_files.get() if not fps_multiplier: return False # If invalid multiplier selected, raise warning try: fps_multiplier = int(fps_multiplier[:-1]) except Exception as e: messagebox.showwarning( title="Select Speed", message= "Please Select Speed of the video from the dropdown menu") return True # Disable the button during converstion to avoid multiple inputs self.btn_convert["state"] = "disabled" # Start the main conversion in a different thread to avoid UI freeze _thread.start_new_thread(bulk_video_converter, (self.files, fps_multiplier, None, self.file_status, self.file_status_percent, self.progress, self.root, self.btn_convert))
def main(): Tk().withdraw() crime_data_file = askopenfilename(filetypes=[("Comma Separated Values", "*.csv")], title="Select city crime data file") crimes = read_crimes(crime_data_file) vector_crime_map = VectorCrimeMap(crimes) window = Tk() window.title("BMORE SAFE") Label(window, text="starting coordinates (Latitude,Longitude").grid(row=0) Label(window, text="ending coordinates (Latitude,Longitude)").grid(row=1) init_lat_entry = Entry(window) init_lon_entry = Entry(window) final_lat_entry = Entry(window) final_lon_entry = Entry(window) init_lat_entry.grid(row=0, column=1) init_lon_entry.grid(row=0, column=2) final_lat_entry.grid(row=1, column=1) final_lon_entry.grid(row=1, column=2) init_latlon_var = StringVar(window) init_latlon_var.set("Preset coords...") final_latlon_var = StringVar(window) final_latlon_var.set("Preset coords...") preset_destinations = { "Homewood Campus", "Medical Campus", "National Aquarium", "BWI Airport", "Cherry Hill" } preset_destination_coordinate_dict = { "Homewood Campus": LatLon(39.329903, -76.620522), "Medical Campus": LatLon(39.299681, -76.593301), "National Aquarium": LatLon(39.286736, -76.608363), "BWI Airport": LatLon(39.177213, -76.668371), "Cherry Hill": LatLon(39.2548293, -76.634412) } init_preset_destinations_dropdown = OptionMenu(window, init_latlon_var, "Preset coords...", *preset_destinations) final_preset_destinations_dropdown = OptionMenu(window, final_latlon_var, "Preset coords...", *preset_destinations) def _set_entry_text(entry, text): entry.delete(0, END) entry.insert(0, str(text)) def _on_change_init_destination_from_dropdown(*args): latlon = preset_destination_coordinate_dict[init_latlon_var.get()] _set_entry_text(init_lat_entry, latlon.lat) _set_entry_text(init_lon_entry, latlon.lon) def _on_change_final_destination_from_dropdown(*args): latlon = preset_destination_coordinate_dict[final_latlon_var.get()] _set_entry_text(final_lat_entry, latlon.lat) _set_entry_text(final_lon_entry, latlon.lon) init_latlon_var.trace("w", _on_change_init_destination_from_dropdown) final_latlon_var.trace("w", _on_change_final_destination_from_dropdown) init_preset_destinations_dropdown.grid(row=0, column=3) final_preset_destinations_dropdown.grid(row=1, column=3) def _process_latlon_input(): init_latlon = LatLon(float(init_lat_entry.get()), float(init_lon_entry.get())) final_latlon = LatLon(float(final_lat_entry.get()), float(final_lon_entry.get())) get_request_response = get_route_json(init_latlon, final_latlon) route_json = json.loads(get_request_response) routes = parse_route_json(route_json) for route in routes: route.crime_score = vector_crime_map.score_route(route) min_crime_score = math.inf min_crime_route = routes[0] for route in routes: if route.crime_score < min_crime_score: min_crime_score = min_crime_route.crime_score min_crime_route = route directions = "" direction_number = 1 for narrative in min_crime_route.narratives: directions += str(direction_number) + ". " + narrative + "\n\n" direction_number += 1 draw_routes(routes).show() showinfo(title="Safest Directions", message=directions) Button(window, text="Go", command=_process_latlon_input).grid(row=3, column=0) mainloop()
#backgroundColor bgColorLabel = Label(root, text = "BackgroundColor") bgColorLabel.grid(row = 3, column = 2) bgColorStr = StringVar() bgColorEntry = Entry(root, width = 10, textvariable = bgColorStr) bgColorEntry.grid(row = 3, column = 3) #optionMenu figureLabel = Label(root, text = "Figure") figureLabel.grid(row = 4, column = 0) turtleStr = StringVar() turtleMenu = OptionMenu(root, turtleStr, shapes[0], *shapes) turtleMenu.grid(row = 4, column = 1) #button clearButton = Button(root, text = "Clear", command = clearF) clearButton.grid(row = 5, column = 0) drawButton = Button(root, text = "Draw", command = DrawF) drawButton.grid(row = 5, column = 1) clearScrButton = Button(root, text = "ClearScreen", command = ClearScrF) clearScrButton.grid(row = 5, column = 2) #labelInformation infoLabelT = Label(root, text = "Info:") infoLabelT.grid(row = 6, column = 0)
class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) # Menu bar self.nav_button1 = tk.Button(self, text='Execute', command=lambda: controller.show_frame(RunWindow)) self.nav_button1.grid(row=1, column=1, sticky='ew') self.nav_button2 = tk.Button(self, text='Remove', command=delete) self.nav_button2.grid(row=1, column=2, sticky='ew') self.nav_button3 = tk.Button(self, text='Email', command=email) self.nav_button3.grid(row=1, column=3, sticky='ew') self.nav_button4 = tk.Button(self, text='About', command=about) self.nav_button4.grid(row=1, column=4, sticky='ew') # Body of Install Window self.description_label = tk.Label(self, text='FSS NOC Tool Installer', font='Helvetica 18 bold', anchor='center', background='#0033A0', foreground='white', relief='sunken') self.description_label.grid(row=2, column=1, columnspan=4, sticky='ew') self.tools = [' Make your selection ', 'Rounding Laptop Tool', 'SnIPT Tool', 'UPS Generator', 'Timezone Conversion', 'SAP Tool', 'Remote GPUpdate', 'Legal Hold Tool', 'RL Last Logon', 'Printer Tool', 'Hostname Converter', 'Data Transfer Tool', 'Timezone Changer'] self.tool_label = tk.StringVar(self) self.opt_menu = OptionMenu(self, self.tool_label, *sorted(self.tools)) self.opt_menu.grid(row=4, column=1, columnspan=4, sticky='ew', pady=20) self.tool_label.trace('w', self.tool_selection) self.start = 'This tool will install all the selected programs to your local system. ' \ 'Please select the item you need and then click Install.\n\n ' \ 'Please provide any issues, or requests to [email protected]' self.tool_description = tk.Label(self, text=self.start, foreground='grey', relief='sunken', wraplength=375, justify='left') self.tool_description.grid(row=5, column=1, columnspan=4, sticky='ew', padx=10, pady=5) # Action Buttons self.tool = tk.Button(self, text='Install', background='green', height=4, width=10, command=self.tool_install) self.tool.grid(row=6, column=1, columnspan=2, padx=10, pady=20) self.cancel = tk.Button(self, text='Cancel', background='red', height=4, width=10, command=self.quit) self.cancel.grid(row=6, column=3, columnspan=2, padx=10, pady=20) # Status Bar self.progress = tk.Label(self, text='', relief='sunken', anchor='w', ) self.progress.grid(row=7, column=1, columnspan=4, sticky='sew', pady=5) def tool_selection(self, *args): """ Sets the tool_description field based off the tool selected. """ self.tool_label.get() if self.tool_label.get() == 'Rounding Laptop Tool': self.tool_description.configure(text='This tool installs the clinic Lexmark, ' 'sets the timezone and wipes the last ' 'logged in user.\n\nThis tool and the following ' 'dependencies will be installed: \n - SQL Commandline Utilities' '\n - 7zip \n - PsExec') elif self.tool_label.get() == 'SnIPT Tool': self.tool_description.configure(text='The SnIPT tool allows you to scan entire ' 'subnet to find all printers that are ' 'installed on all live PCs at the time of ' 'execution.\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip ' '\n - PowerShell v5.0 or higher' '\n - PsExec \n - Nmap v7.7') elif self.tool_label.get() == 'UPS Generator': self.tool_description.configure(text='This is a PowerShell script that pulls ' 'the Remedy information out of all the ' 'outstanding UPS tickets.\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip ' '\n - PowerShell v5.0 or higher') elif self.tool_label.get() == 'Timezone Conversion': self.tool_description.configure(text='This tool tells you at what time a ' 'maintenance window should be set for.' '\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip') elif self.tool_label.get() == 'SAP Tool': self.tool_description.configure(text='This tool remotely installs SAP 7.40 on ' 'a windows computer.\n\nThis tool and the ' 'following dependencies will be installed: ' '\n - 7zip') elif self.tool_label.get() == 'Remote GPUpdate': self.tool_description.configure(text='This tool is used to to run gpupdate ' 'on a remote computer, useful before ' 'running the Rounding Laptop tool.' '\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip') elif self.tool_label.get() == 'Legal Hold Tool': self.tool_description.configure(text='The Legal Hold Tool allows users to get the ' 'list of all users of a machine and transfer user ' 'files to East or West division legal directories.' '\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip' '\n - Python 3.6.5 or higher') elif self.tool_label.get() == 'RL Last Logon': self.tool_description.configure(text='A tool that scans for every service tag in the ' '"RL" queue to show the rounding laptops that have ' 'been logged in since configured at the NOC, also ' 'grabbing the most recent I\n\nThis tool and the ' 'following dependencies will be installed: \n - 7zip ' '\n - PowerShell v5.0 or higher') elif self.tool_label.get() == 'Printer Tool': self.tool_description.configure(text='This tool allows for remote printer management ' 'of a windows computer, including installing, ' 'removing printers, and renaming printers') elif self.tool_label.get() == 'Hostname Converter': self.tool_description.configure(text='The Hostname converter tool allows the ' 'user to get the IP address of a host ' 'automatically.\n\nThis tool and the following ' 'dependencies will be installed: \n - 7zip') elif self.tool_label.get() == 'Data Transfer Tool': self.tool_description.configure(text='FSS Data Transfer Tool allows users ' 'to transfer files from an old ' 'computer to a new computer.\n\nThis ' 'tool and the following dependencies ' 'will be installed: \n - 7zip') elif self.tool_label.get() == 'Timezone Changer': self.tool_description.configure(text='This tool sets the timezone on a remote ' 'windows computer.\n\nThis tool and the ' 'following dependencies will be installed: ' '\n - 7zip \n - PowerShell v5.0 or higher' '\n - PsExec') else: self.tool_description.configure(text='Something went wrong.') return self.tool_description def tool_install(self, *args): """ Installs the selected tool""" self.tool_label.get() if self.tool_label.get() == 'Rounding Laptop Tool': rlpi_install() self.progress.configure(text='RLPI files installed') elif self.tool_label.get() == 'SnIPT Tool': snipt_install() self.progress.configure(text='SnIPT files installed') elif self.tool_label.get() == 'UPS Generator': ups_install() self.progress.configure(text='UPS Generator files installed') elif self.tool_label.get() == 'Timezone Conversion': time_install() self.progress.configure(text='Timezone Conversion files installed') elif self.tool_label.get() == 'SAP Tool': sap_install() self.progress.configure(text='SAP files installed') elif self.tool_label.get() == 'Remote GPUpdate': gpupdate_install() self.progress.configure(text='GPUpdate files installed') elif self.tool_label.get() == 'Legal Hold Tool': legal_install() self.progress.configure(text='Legal Hold files installed') elif self.tool_label.get() == 'RL Last Logon': logon() self.progress.configure(text='RL Last Logon files installed') elif self.tool_label.get() == 'FSS Printer Tool': printer() self.progress.configure(text='Printer Tool files installed') elif self.tool_label.get() == 'Hostname Converter': hostname() self.progress.configure(text='Hostname files installed') elif self.tool_label.get() == 'FSS Data Transfer Tool': transfer() self.progress.configure(text='Data Transfer files installed') elif self.tool_label.get() == 'Timezone Changer': time_change() self.progress.configure(text='Timezone Changer files installed') else: self.tool_description.configure(text='Something went wrong!!!') self.tool_description.configure(text=self.start) return self.progress
class GUI(object): '''Stellt die Oberflaeche dar. Alle steuerden Taetigkeiten werden (sollten) vom Controller Objekt uebernommen werden. ''' def __init__(self): ''' Constructor ''' self.root = Tk() self.root.title("DinnerLog") self.root.minsize(800, 600) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(0, weight=1) self.root.grid_rowconfigure(1, weight=3) # Ein Frame für alles, das mit Zutaten zu tun hat self.fr_zutaten = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Zutaten") self.fr_zutaten.grid_columnconfigure(0, weight=1) self.fr_zutaten.grid_rowconfigure(0, weight=1) self.fr_zutaten.grid(row=0, column=0, sticky="NSWE") self.lb_zutaten = Listbox(self.fr_zutaten) sb_zutaten = Scrollbar(self.lb_zutaten, orient=VERTICAL) self.lb_zutaten.configure(yscrollcommand=sb_zutaten.set) sb_zutaten.config(command=self.lb_zutaten.yview) sb_zutaten.pack(side="right", fill="both") self.lb_zutaten.grid(row=0, column=0, sticky="NSEW") self._addNeueZutatFrame() # Ein Frame in den alles, das mit Mahlzeiten zu tun hat, kommt self.fr_mahlzeit = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Mahlzeiten") self.fr_mahlzeit.grid_columnconfigure(0, weight=1) self.fr_mahlzeit.grid_rowconfigure(0, weight=1) self.fr_mahlzeit.grid(row=1, column=0, sticky="NSWE") self._addNeueMahlzeitFrame() self.lb_mahlzeiten = Listbox(self.fr_mahlzeit, selectmode=SINGLE) sb_mahlzeiten = Scrollbar(self.lb_mahlzeiten, orient=VERTICAL) sb_mahlzeiten.configure(command=self.lb_mahlzeiten.yview) self.lb_mahlzeiten.configure(yscrollcommand=sb_mahlzeiten.set) sb_mahlzeiten.pack(side="right", fill="both") self.lb_mahlzeiten.grid(row=0, column=0, sticky="NSEW") fr_neu_ok = Frame(self.fr_mahlzeit) fr_neu_ok.grid(row=1, column=0, columnspan=2, sticky="E") self.btn_neu = Button(fr_neu_ok, text="Neu") self.btn_neu.pack(side="left") self.btn_mahlzeit_als_zt = Button(fr_neu_ok, text="Als Zutat") self.btn_mahlzeit_als_zt.pack(anchor=E, side="right") self.btn_insert = Button(fr_neu_ok, text="Hinzufuegen") self.btn_insert.pack(anchor=E, side="right") self.btn_update = Button(fr_neu_ok, text="Update") self.btn_update.pack(anchor=E, side="right") self.btn_delete = Button(fr_neu_ok, text="Loeschen") self.btn_delete.pack(anchor=E, side="right") # Ein Frame der Statistiken darstellt self.fr_stats = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Statistik") self.fr_stats.grid(row=3, column=0, sticky="NSWE") #self.cv_stats = Canvas(self.fr_stats, height=80, width=600) #self.cv_stats.create_line(2,5,598,5, fill="#bbb") def _addNeueMahlzeitFrame(self): self.fr_neue_mz = Frame(self.fr_mahlzeit) self.fr_neue_mz.grid_rowconfigure(2, weight=1) self.fr_neue_mz.grid(row=0, column=1, sticky="WSNE") lbl_name = Label(self.fr_neue_mz, text="Name:") lbl_name.grid(row=0, column=0, sticky="NW") self.en_name = Entry(self.fr_neue_mz) self.en_name.grid(row=0, column=1, columnspan=2, sticky="WNE") lbl_zutat = Label(self.fr_neue_mz, text="Zutaten:") lbl_zutat.grid(row=1, column=0, sticky="NW") self.lb_zutat = Listbox(self.fr_neue_mz) sb_zutat = Scrollbar(self.lb_zutat, orient=VERTICAL) self.lb_zutat.configure(yscrollcommand=sb_zutat.set) sb_zutat.configure(command=self.lb_zutat.yview) sb_zutat.pack(side="right", fill="both") self.lb_zutat.grid(row=2, column=0, columnspan=3, sticky="NWSE") self.var_zutat = StringVar(self.fr_neue_mz) self.opt_zutat = OptionMenu(self.fr_neue_mz, self.var_zutat, "Auswahl") self.opt_zutat.grid(row=3, column=0) self.en_menge = Entry(self.fr_neue_mz) self.en_menge.grid(row=3, column=1) self.btn_mahlzeit_hinzu = Button(self.fr_neue_mz, text="Hinzu") self.btn_mahlzeit_hinzu.grid(row=3, column=2, sticky="E") def _addNeueZutatFrame(self): fr_neue_zt = Frame(self.fr_zutaten) fr_neue_zt.grid(row=0, column=2,sticky="NWSE") lbl_name = Label(fr_neue_zt, text="Name:") lbl_name.grid(row=0, column=0, sticky="W") self.en_name_zt = Entry(fr_neue_zt) self.en_name_zt.grid(row=0, column=1, columnspan=2, sticky="WE") lbl_fett = Label(fr_neue_zt, text="Fett:") lbl_fett.grid(row=1, column=0, sticky="W") self.en_fett = Entry(fr_neue_zt) self.en_fett.grid(row=1, column=1, columnspan=2) lbl_eiweiss = Label(fr_neue_zt, text="Eiweiss:") lbl_eiweiss.grid(row=2, column=0, sticky="W") self.en_eiweiss = Entry(fr_neue_zt) self.en_eiweiss.grid(row=2, column=1, columnspan=2) lbl_kh = Label(fr_neue_zt, text="Kohlenhy.:") lbl_kh.grid(row=3, column=0, sticky="W") self.en_kh = Entry(fr_neue_zt) self.en_kh.grid(row=3, column=1, columnspan=2) self.btn_zutat_insert = Button(fr_neue_zt, text="Hinzu") self.btn_zutat_insert.grid(row=4, column=1, sticky="E") self.btn_zutat_update = Button(fr_neue_zt, text="Update") self.btn_zutat_update.grid(row=5, column=1, sticky="E") self.btn_zutat_delete = Button(fr_neue_zt, text="Loeschen") self.btn_zutat_delete.grid(row=6, column=1, sticky="E")
class ExpenseTab: # Use for option selection for currency currency_code_list = [ 'AUD', 'CAD', 'CHF', 'CNY', 'DKK', 'EUR', 'GBP', 'INR', 'JPY', 'LBP', 'NOK', 'NZD', 'MAD', 'USD', 'SEK', 'TND' ] convert_to_EUR = [ 0.62, 0.65, 0.93, 0.13, 0.13, 1, 1.11, 0.011, 0.008, 0.00056, 0.094, 0.58, 0.092, 0.85, 0.098, 0.31 ] def __init__(self, tab_control, expense_controller, user_controller, username): """Initializes the expense tab and creates all elements of the visual interface""" # Input for the expense interface self.expense_controller = expense_controller self.user_controller = user_controller self.username = username self.category_list = self.user_controller.get_categories(self.username) self.chosen_currency = StringVar() self.chosen_category = StringVar() self.description = StringVar() self.price = StringVar() self.price_in_euro = StringVar() self.date = StringVar() self.currency_EUR_dict = { self.currency_code_list[i]: self.convert_to_EUR[i] for i in range(len(self.currency_code_list)) } try: # try to load latest currency conversion codes through an API response = requests.get('https://api.ratesapi.io/api/latest') for c in self.currency_code_list: try: # try to load conversion rate for specific currency self.currency_EUR_dict[c] = 1 / response.json()['rates'][c] except KeyError: # if not available (e.g. LBP) the hard-coded conversion rate is used pass except requests.exceptions.RequestException as e: # if no internet connection is available or the server is down, hard-coded conversion rates are used print(e) self.id_expenseItem = 0 total = self.expense_controller.total_expenses(self.username) self.sum_expenses = StringVar(value=f"Sum of all expenses: {total}€") self.budget_message = StringVar() self.expense_tab = ttk.Frame(tab_control) tab_control.add(self.expense_tab, text='Expenses') Label(self.expense_tab, text="New expense:", font='Helvetica 16 bold').grid(row=0, column=0, padx=15, pady=15, sticky='w') # DESCRIPTION Label(self.expense_tab, text="Description:").grid(row=1, column=0, padx=(15, 0), pady=2, sticky='w') Entry(self.expense_tab, textvariable=self.description).grid(row=1, column=1, pady=2, sticky="ew") # CATEGORY Label(self.expense_tab, text="Category:").grid(row=1, column=2, pady=2) self.category_select = OptionMenu(self.expense_tab, self.chosen_category, self.category_list[0], *self.category_list) self.category_select.grid(row=1, column=3, padx=(0, 15), pady=2, sticky="ew") # PRICE Label(self.expense_tab, text="Price:").grid(row=2, column=0, padx=(15, 0), pady=2, sticky='w') Entry(self.expense_tab, textvariable=self.price).grid(row=2, column=1, pady=2, sticky="ew") # CURRENCY OPTION Label(self.expense_tab, text="Currency:").grid(row=2, column=2, pady=2) OptionMenu(self.expense_tab, self.chosen_currency, self.currency_code_list[5], *self.currency_code_list)\ .grid(row=2, column=3, padx=(0, 15), pady=2, sticky="ew") # DATE Label(self.expense_tab, text="Date:").grid(row=3, column=0, padx=(15, 0), pady=2, sticky='w') DateEntry(self.expense_tab, background='darkblue', foreground='white', borderwidth=2, textvariable=self.date, date_pattern='dd/MM/yyyy').grid(row=3, column=1, pady=2, sticky="ew") # INSERT BUTTON Button(self.expense_tab, text="Insert", command=self.insert_expense_data).grid(row=4, column=1, pady=2, sticky="ew") Label(self.expense_tab, text="Your expenses:", font='Helvetica 16 bold').grid(row=5, column=0, padx=15, pady=15, sticky='w') # TOTAL EXPENSE Label(self.expense_tab, textvariable=self.sum_expenses).grid(row=6, column=0, padx=(15, 0), sticky='w') # BUDGET DIFFERENCE self.budgetLabel = Label(self.expense_tab, textvariable=self.budget_message) self.budgetLabel.grid(row=7, column=0, columnspan=2, padx=(15, 0), sticky='w') # set budget difference value budget_message = self.calculate_budget_level() self.budget_message.set(budget_message) # TREEVIEW WITH SCROLLBAR y_scroll = Scrollbar(self.expense_tab, orient='vertical') y_scroll.grid(row=8, column=5, padx=(0, 15), pady=(40, 15), sticky='nsw') self.treeExpense = ttk.Treeview(self.expense_tab, columns=('Date', 'Category', 'Description', 'Price', 'Currency', 'Price in EUR'), yscrollcommand=y_scroll.set, height=20) y_scroll['command'] = self.treeExpense.yview self.treeExpense.grid(row=8, column=0, columnspan=5, padx=(15, 0), pady=15) # Set the treeview columns self.treeExpense.heading('#0', text='Item Id') self.treeExpense.column("#0", minwidth=0, width=0) self.treeExpense.heading('#1', text='Date') self.treeExpense.column("#1", minwidth=0, width=120) self.treeExpense.heading('#2', text='Category') self.treeExpense.column("#2", minwidth=0, width=280) self.treeExpense.heading('#3', text='Description') self.treeExpense.column("#3", minwidth=0, width=280) self.treeExpense.heading('#4', text='Price') self.treeExpense.column("#4", minwidth=0, width=100) self.treeExpense.heading('#5', text='Currency') self.treeExpense.column("#5", minwidth=0, width=100) self.treeExpense.heading('#6', text='Price in EUR') self.treeExpense.column("#6", minwidth=0, width=100) # Restore display in table from the expense database self.update_treeview_from_existing_database() # DELETE BUTTON # Configure delete button style to be red style = Style() style.configure('W.TButton', foreground='red') Button(self.expense_tab, text="Delete", style='W.TButton', command=self.delete_expense_data).grid(row=9, column=4, padx=15, sticky="e") # SORT THE PRICE: CALL FUNCTION col1 = "Price" col2 = "Price in EUR" col3 = "Date" self.treeExpense.heading( col1, text=col1, command=lambda: self.treeview_sort_price(col1, False)) self.treeExpense.heading( col2, text=col2, command=lambda: self.treeview_sort_price(col2, False)) # SORT THE DATE: CALL FUNCTION self.treeExpense.heading( col3, text=col3, command=lambda s=col3: self.treeview_sort_date(col3, False)) def update_treeview_from_existing_database(self): """If the database of expenses already exist for this username, display it back into the treeview""" database = self.expense_controller.get_expenses_for_user(self.username) for id_item in database: self.treeExpense.insert( '', 0, id_item, values=(database[id_item]["date"], database[id_item]["category"], database[id_item]["description"], database[id_item]["price"], database[id_item]["currency"], database[id_item]["price_in_euro"])) self.id_expenseItem = id_item def insert_expense_data(self): """ Add a new expense item both to the treeview and to the database. Then update the sum of all expenses and the budget difference. This function is called when clicking the 'Insert' button """ currency = self.chosen_currency.get() category = self.chosen_category.get() description = self.description.get() price = self.price.get() expense_date = self.date.get() # replace comma with point in order to make it possible to cast to float price = price.replace(',', '.') # Check if it is numeric if not is_float_number(price): messagebox.showerror("INPUT ERROR", "The price must be a (floating) number") else: self.id_expenseItem = self.id_expenseItem + 1 price = float(price) price_in_euro = self.expense_controller.convert_in_euro( price, currency, self.currency_EUR_dict) # display into the Expense gui table # https://www.askpython.com/python-modules/tkinter/tkinter-treeview-widget self.treeExpense.insert('', 0, self.id_expenseItem, values=(expense_date, category, description, price, currency, price_in_euro)) # update the expense database through expense controller self.expense_controller.create_expense(self.username, self.id_expenseItem, expense_date, category, description, price, currency, price_in_euro) total = self.expense_controller.total_expenses(self.username) self.sum_expenses.set(f"Sum of all expenses: {total}€") budget_message = self.calculate_budget_level() self.budget_message.set(budget_message) def delete_expense_data(self): """ Remove the selected item from the treeview and the database, then update the sum of all expenses and the budget difference. This function is called when clicking the 'Delete' button """ try: id_expense_selected = int(self.treeExpense.focus()) self.treeExpense.delete(id_expense_selected) # remove the selected expense id in the database as well self.expense_controller.delete_expense(self.username, id_expense_selected) except ValueError: messagebox.showerror("Delete Error", "Select an item to be deleted") total = self.expense_controller.total_expenses(self.username) self.sum_expenses.set(f"Sum of all expenses: {total}€") budget_message = self.calculate_budget_level() self.budget_message.set(budget_message) def refresh_categories(self, category_list): """Refresh the category drop-down menu. This is called after configuring categories in the preferences""" self.category_list = category_list self.category_select = OptionMenu(self.expense_tab, self.chosen_category, self.category_list[0], *self.category_list) self.category_select.grid(row=1, column=3, pady=5, sticky="ew") def treeview_sort_price(self, col, reverse: bool): """Sort the table by price when clicking on the price column""" data_list = [(float(self.treeExpense.set(k, col)), k) for k in self.treeExpense.get_children("")] data_list.sort(reverse=reverse) # rearrange items in sorted positions for index, (val, k) in enumerate(data_list): self.treeExpense.move(k, "", index) # reverse sort next time self.treeExpense.heading( column=col, text=col, command=lambda _col=col: self.treeview_sort_price( _col, not reverse), ) def treeview_sort_date(self, date_col, reverse): """Sort the table by date when clicking on the date column""" l = [(self.treeExpense.set(k, date_col), k) for k in self.treeExpense.get_children('')] sortedArray = sorted( l, key=lambda x_lab: datetime.strptime(x_lab[0], '%d/%m/%Y'), reverse=not reverse) for index, (val, k) in enumerate(sortedArray): self.treeExpense.move(k, '', index) self.treeExpense.heading( column=date_col, text=date_col, command=lambda _date_col=date_col: self.treeview_sort_date( _date_col, not reverse), ) def calculate_budget_level(self): """ Calculates whether the custom budget (in preferences) is already exceeded or not and generate a message to display. """ budget = self.user_controller.get_budget(self.username) if budget[0]: today = date.today() if budget[1] == 'per day': start_date = today elif budget[1] == 'per week': start_date = today - timedelta(days=today.weekday()) elif budget[1] == 'per month': start_date = today.replace(day=1) elif budget[1] == 'per year': start_date = today.replace(month=1).replace(day=1) expenses = self.expense_controller.get_expenses_for_user( self.username) delete = [] for k, v in expenses.items(): if datetime.date(datetime.strptime(v['date'], '%d/%m/%Y')) < start_date: delete.append(k) # we cannot delete items from dictionary while iterating the dict, therefore we store indices to delete in # list and delete the corresponding elements later for k in delete: del expenses[k] total = sum([e['price_in_euro'] for e in expenses.values()]) difference = round((float(budget[0]) - total), 2) if difference > 0: message = f'You have {difference}€ left from your budget which is {budget[0]}€ {budget[1]}.' self.budgetLabel.configure(foreground='green') elif difference == 0: message = f'Attention! You have nothing left from your budget which is {budget[0]}€ {budget[1]}.' self.budgetLabel.configure(foreground='orange') else: message = f'Attention! You exceeded your budget ({budget[0]}€ {budget[1]}) by {-1*difference}€!' self.budgetLabel.configure(foreground='red') return message return "You haven't set a budget yet. You can do so in the preferences."
class GUI(object): '''Stellt die Oberflaeche dar. Alle steuerden Taetigkeiten werden (sollten) vom Controller Objekt uebernommen werden. ''' def __init__(self): ''' Constructor ''' self.root = Tk() self.root.title("DinnerLog") self.root.minsize(800, 600) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(0, weight=1) self.root.grid_rowconfigure(1, weight=3) # Ein Frame für alles, das mit Zutaten zu tun hat self.fr_zutaten = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Zutaten") self.fr_zutaten.grid_columnconfigure(0, weight=1) self.fr_zutaten.grid_rowconfigure(0, weight=1) self.fr_zutaten.grid(row=0, column=0, sticky="NSWE") self.lb_zutaten = Listbox(self.fr_zutaten) sb_zutaten = Scrollbar(self.lb_zutaten, orient=VERTICAL) self.lb_zutaten.configure(yscrollcommand=sb_zutaten.set) sb_zutaten.config(command=self.lb_zutaten.yview) sb_zutaten.pack(side="right", fill="both") self.lb_zutaten.grid(row=0, column=0, sticky="NSEW") self._addNeueZutatFrame() # Ein Frame in den alles, das mit Mahlzeiten zu tun hat, kommt self.fr_mahlzeit = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Mahlzeiten") self.fr_mahlzeit.grid_columnconfigure(0, weight=1) self.fr_mahlzeit.grid_rowconfigure(0, weight=1) self.fr_mahlzeit.grid(row=1, column=0, sticky="NSWE") self._addNeueMahlzeitFrame() self.lb_mahlzeiten = Listbox(self.fr_mahlzeit, selectmode=SINGLE) sb_mahlzeiten = Scrollbar(self.lb_mahlzeiten, orient=VERTICAL) sb_mahlzeiten.configure(command=self.lb_mahlzeiten.yview) self.lb_mahlzeiten.configure(yscrollcommand=sb_mahlzeiten.set) sb_mahlzeiten.pack(side="right", fill="both") self.lb_mahlzeiten.grid(row=0, column=0, sticky="NSEW") fr_neu_ok = Frame(self.fr_mahlzeit) fr_neu_ok.grid(row=1, column=0, columnspan=2, sticky="E") self.btn_neu = Button(fr_neu_ok, text="Neu") self.btn_neu.pack(side="left") self.btn_mahlzeit_als_zt = Button(fr_neu_ok, text="Als Zutat") self.btn_mahlzeit_als_zt.pack(anchor=E, side="right") self.btn_insert = Button(fr_neu_ok, text="Hinzufuegen") self.btn_insert.pack(anchor=E, side="right") self.btn_update = Button(fr_neu_ok, text="Update") self.btn_update.pack(anchor=E, side="right") self.btn_delete = Button(fr_neu_ok, text="Loeschen") self.btn_delete.pack(anchor=E, side="right") # Ein Frame der Statistiken darstellt self.fr_stats = Labelframe(self.root, borderwidth=2, relief=GROOVE, text="Statistik") self.fr_stats.grid(row=3, column=0, sticky="NSWE") #self.cv_stats = Canvas(self.fr_stats, height=80, width=600) #self.cv_stats.create_line(2,5,598,5, fill="#bbb") def _addNeueMahlzeitFrame(self): self.fr_neue_mz = Frame(self.fr_mahlzeit) self.fr_neue_mz.grid_rowconfigure(2, weight=1) self.fr_neue_mz.grid(row=0, column=1, sticky="WSNE") lbl_name = Label(self.fr_neue_mz, text="Name:") lbl_name.grid(row=0, column=0, sticky="NW") self.en_name = Entry(self.fr_neue_mz) self.en_name.grid(row=0, column=1, columnspan=2, sticky="WNE") lbl_zutat = Label(self.fr_neue_mz, text="Zutaten:") lbl_zutat.grid(row=1, column=0, sticky="NW") self.lb_zutat = Listbox(self.fr_neue_mz) sb_zutat = Scrollbar(self.lb_zutat, orient=VERTICAL) self.lb_zutat.configure(yscrollcommand=sb_zutat.set) sb_zutat.configure(command=self.lb_zutat.yview) sb_zutat.pack(side="right", fill="both") self.lb_zutat.grid(row=2, column=0, columnspan=3, sticky="NWSE") self.var_zutat = StringVar(self.fr_neue_mz) self.opt_zutat = OptionMenu(self.fr_neue_mz, self.var_zutat, "Auswahl") self.opt_zutat.grid(row=3, column=0) self.en_menge = Entry(self.fr_neue_mz) self.en_menge.grid(row=3, column=1) self.btn_mahlzeit_hinzu = Button(self.fr_neue_mz, text="Hinzu") self.btn_mahlzeit_hinzu.grid(row=3, column=2, sticky="E") def _addNeueZutatFrame(self): fr_neue_zt = Frame(self.fr_zutaten) fr_neue_zt.grid(row=0, column=2, sticky="NWSE") lbl_name = Label(fr_neue_zt, text="Name:") lbl_name.grid(row=0, column=0, sticky="W") self.en_name_zt = Entry(fr_neue_zt) self.en_name_zt.grid(row=0, column=1, columnspan=2, sticky="WE") lbl_fett = Label(fr_neue_zt, text="Fett:") lbl_fett.grid(row=1, column=0, sticky="W") self.en_fett = Entry(fr_neue_zt) self.en_fett.grid(row=1, column=1, columnspan=2) lbl_eiweiss = Label(fr_neue_zt, text="Eiweiss:") lbl_eiweiss.grid(row=2, column=0, sticky="W") self.en_eiweiss = Entry(fr_neue_zt) self.en_eiweiss.grid(row=2, column=1, columnspan=2) lbl_kh = Label(fr_neue_zt, text="Kohlenhy.:") lbl_kh.grid(row=3, column=0, sticky="W") self.en_kh = Entry(fr_neue_zt) self.en_kh.grid(row=3, column=1, columnspan=2) self.btn_zutat_insert = Button(fr_neue_zt, text="Hinzu") self.btn_zutat_insert.grid(row=4, column=1, sticky="E") self.btn_zutat_update = Button(fr_neue_zt, text="Update") self.btn_zutat_update.grid(row=5, column=1, sticky="E") self.btn_zutat_delete = Button(fr_neue_zt, text="Loeschen") self.btn_zutat_delete.grid(row=6, column=1, sticky="E")
class Parameters_wind(object): #Here y= row and x = column def __init__(self, master): self._rules = "RL" self._Game = [] self._indice = 0 frame = Frame(master) frame.grid() tabControl = ttk.Notebook(master) tabControl.configure(width=420, height=600) self.main_tab = ttk.Frame(tabControl) tabControl.add(self.main_tab, text="Settings") tabControl.grid() self.about_tab = ttk.Frame(tabControl) tabControl.add(self.about_tab, text="About") tabControl.grid() self.dimension = IntVar() self.dimension.set(value=50) self.chkValue = BooleanVar() self.chkValue.set(True) self.chkValue_two = BooleanVar() self.chkValue_two.set(False) self.nbr_of_ant = IntVar() self.nbr_of_ant.set(value=1) self.speed_opts = ['0', '1000', '500', '250', '100', '50', '10', '0'] self.speed = StringVar() self.black_case_nbr = IntVar() self.black_case_nbr.set(value=0) self.about_page() self.main_page() def main_page(self): self.label_dimension = Label( self.main_tab, text="How many rows and columns do you want ?") self.label_dimension.grid(column=0, row=0, sticky='w') self.scale_dimension = Scale(self.main_tab, orient='horizontal', from_=25, to=200, variable=self.dimension, tickinterval=25, length=200) self.scale_dimension.grid(column=0, row=1, padx=5, pady=5) self.frame_dimension = Labelframe(self.main_tab, text="Order of ideas :", height=60, width=300) self.frame_dimension.grid(column=0, row=2, sticky='w') dimension_frame_label = [ "<50 this is a bit small", "50<x<150 ideal dimension", ">150 quite such huge" ] for i in range(len(dimension_frame_label)): texte = dimension_frame_label[i] self.dimension_frame_label = Label(self.frame_dimension, text=f"{texte}") self.dimension_frame_label.grid(column=0, row=i, sticky='w') self.dimension_frame_label.grid(column=0, row=2, sticky='w') self.label_ant = Label(self.main_tab, text="How many ant(s) do you want ?") self.label_ant.grid(column=0, row=3, sticky='w') self.scale_ant = Scale(self.main_tab, orient='horizontal', from_=1, to=10, variable=self.nbr_of_ant, tickinterval=2, length=200) self.scale_ant.grid(column=0, row=4, padx=5, pady=5) self.speed_label = Label(self.main_tab, text="Delay in millisecond :") self.speed_label.grid(column=0, row=5, sticky='w') self.speed_menu = OptionMenu(self.main_tab, self.speed, *self.speed_opts) self.speed_menu.grid(column=1, row=5, sticky='w') self.black_case_label = Label(self.main_tab, text="Percentage of black cells :") self.black_case_label.grid(column=0, row=6, sticky='w') self.black_case = Scale(self.main_tab, orient='horizontal', from_=0, to=99, variable=self.black_case_nbr, tickinterval=10, length=200) self.black_case.grid(column=0, row=7, padx=5, pady=5) self.frame_rules = Labelframe(self.main_tab, text="Rules setting:", height=100, width=400) self.frame_rules.grid(column=0, row=8, sticky='w') self.label_rules = Label(self.frame_rules, text="Rules :" + str(self._rules)) self.label_rules.grid(column=0, row=0, sticky='w', columnspan=3) self.button_F = Button(self.frame_rules, text="F", command=self.F) self.button_F.grid(column=1, row=1, padx=5, pady=5) self.button_L = Button(self.frame_rules, text="L", command=self.L) self.button_L.grid(column=0, row=2, padx=5, pady=5) self.button_clean = Button(self.frame_rules, text="Clean", command=self.clean) self.button_clean.grid(column=1, row=2, padx=5, pady=5) self.button_R = Button(self.frame_rules, text="R", command=self.R) self.button_R.grid(column=2, row=2, padx=5, pady=5) self.button_B = Button(self.frame_rules, text="B", command=self.B) self.button_B.grid(column=1, row=3, padx=5, pady=5) self.chk = Checkbutton(self.main_tab, text='Grid', var=self.chkValue) self.chk.grid(column=0, row=9) self.chk_two = Checkbutton(self.main_tab, text='Desctructive collision', var=self.chkValue_two) self.chk_two.grid(column=1, row=9) self.button_simulator = Button(self.main_tab, text="Go to simulation auto", command=self.simulation_ants) self.button_simulator.grid(column=0, row=10) self.button_simulator_steps = Button( self.main_tab, text="Go to simulation step by step", command=self.simulation_steps) self.button_simulator_steps.grid(column=1, row=10, pady=15) def about_page(self): self.ligne = 0 about_label = [ "Students in the project :", " -Esteban Mathia", " -Victor Minne", " -Tom Cleenewerck" ] for i in range(len(about_label)): texte = about_label[i] self.about_label = Label(self.about_tab, text=f"{texte}") self.about_label.grid(column=0, row=self.ligne, sticky='w') self.ligne += 1 esteban = [ "Esteban :", " +33675549372", " [email protected]" ] victor = ["Victor :", " +33611815452", " [email protected]"] tom = ["Tom :", " +33750370032", " [email protected]"] info_contribuator = [esteban, victor, tom] for i in range(len(info_contribuator)): for j in range(len(info_contribuator[i])): texte = info_contribuator[i][j] self.about_label = Label(self.about_tab, text=f"{texte}") self.about_label.grid(column=0, row=self.ligne, sticky='w') self.ligne += 1 def F(self): if len(self._rules) < 12: self._rules += "F" else: messagebox.showinfo("Info", "You arrive to maximum rules") self.actu_rules() def L(self): if len(self._rules) < 12: self._rules += "L" else: messagebox.showinfo("Info", "You arrive to maximum rules") self.actu_rules() def R(self): if len(self._rules) < 12: self._rules += "R" else: messagebox.showinfo("Info", "You arrive to maximum rules") self.actu_rules() def B(self): if len(self._rules) < 12: self._rules += "B" else: messagebox.showinfo("Info", "You arrive to maximum rules") self.actu_rules() def clean(self): self._rules = "" self.actu_rules() def actu_rules(self): self.label_rules.config(text="Rules :" + str(self._rules)) def simulation_ants(self): if len(self._rules) > 0: threading._start_new_thread(self.new_board, ()) self._Game.append("") time.sleep(0.2) self._indice += 1 else: messagebox.showwarning( "Warning", "The Rules are incorrect, please complete it") def new_board(self): row = self.dimension.get() column = self.dimension.get() number_of_ant = self.nbr_of_ant.get() speed = int(self.speed.get()) / 1000 percentage = self.black_case_nbr.get() border = self.chkValue.get() collision = self.chkValue_two.get() self._Game[self._indice] = Board_multiple_ants(collision, self._rules, border, self._indice, row, column, percentage, number_of_ant, speed) def simulation_steps(self): if len(self._rules) > 0: threading._start_new_thread(self.new_board_steps, ()) self._Game.append("") time.sleep(0.2) self._indice += 1 else: messagebox.showwarning( "Warning", "The Rules are incorrect, please complete it") def new_board_steps(self): row = self.dimension.get() column = self.dimension.get() number_of_ant = self.nbr_of_ant.get() percentage = self.black_case_nbr.get() border = self.chkValue.get() collision = self.chkValue_two.get() self._Game[self._indice] = Simulator_steps(collision, self._rules, self._indice, row, column, percentage, number_of_ant, border)
#=========================================== # make the interface compoments #=========================================== label = Label(root, text = " ") label.grid(row = 0, column = 1, columnspan = 1) typeLabel = Label(root, text = "Type") typeLabel.grid(row = 1, column = 3,columnspan = 1) typeStr = StringVar() typeOptionMenu = OptionMenu(root, typeStr, type[0], *type) typeOptionMenu.grid(row = 1, column = 4, columnspan = 1) penLabel = Label(root, text = "PenColor") penLabel.grid(row = 2, column = 3,columnspan = 1) penColorStr = StringVar() penColorOptionMenu = OptionMenu(root, penColorStr, penColor[0], *penColor) penColorOptionMenu.grid(row = 2, column = 4,columnspan = 1) #number=================================================================== numberLabel = Label(root, text = "Order") numberLabel.grid(row = 3, column = 3, columnspan =1)
class GUI(): def __init__(self): self.root = ThemedTk(theme="radiance") INIT_WIDTH, INIT_HEIGHT = self.root.winfo_screenwidth( ), self.root.winfo_screenheight() boldStyle = ttk.Style() boldStyle.configure("Bold.TButton", font=('Sans', '12', 'bold')) #icon_loc = os.path.join(os.getcwd(),ICON_NAME) #img = ImageTk.PhotoImage(master = self.root, file=icon_loc) #self.root.wm_iconbitmap(img) #self.root.ttk.call('wm', 'iconphoto', self.root._w, img) self.root.title("Form Labeller") self.root.maxsize(INIT_WIDTH, INIT_HEIGHT) self.supported_formats = SUPPORTED_FORMATS self.left_frame = Frame(self.root, width=BUTTON_WIDTH) self.top_frame1 = Frame(self.left_frame, width=BUTTON_WIDTH, height=int(INIT_HEIGHT / 2)) self.top_frame = Frame(self.left_frame, width=BUTTON_WIDTH, height=INIT_HEIGHT - int(INIT_HEIGHT / 2)) self.bottom_frame = Frame(self.root, width=INIT_WIDTH - BUTTON_WIDTH) self.load_image_directory_button = Button(self.top_frame1, text='Open Folder', command=self.load_directory, width=int(BUTTON_WIDTH), style="Bold.TButton") self.load_image_directory_button.grid(row=OPEN_FOLDER_ROW, columnspan=2, sticky=tk.W + tk.E) self.prev_img_button = Button(self.top_frame1, text='← Prev', command=self.previous_img, state=tk.DISABLED, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.prev_img_button.grid(row=PREV_ROW, column=0, sticky=tk.W + tk.E) self.next_img_button = Button(self.top_frame1, text='Next → ', command=self.next_img, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.next_img_button.grid(row=NEXT_COL, column=1, sticky=tk.W + tk.E) self.save_image_button = Button(self.top_frame1, text='Save ', command=self.saver, width=int(BUTTON_WIDTH), style="Bold.TButton") self.save_image_button.grid(row=SAVE_ROW, columnspan=2, sticky=tk.W + tk.E) self.delete_poly_button = Button(self.top_frame, text='Delete Selected', command=self.delete_selected, width=int(BUTTON_WIDTH), style="Bold.TButton") self.delete_poly_button.grid(row=DEL_SELECTED_ROW, columnspan=2, sticky=tk.W + tk.E) self.type_choices = TYPE_CHOICES self.variable = StringVar(self.top_frame) self.variable.set(self.type_choices[0]) self.type_options = OptionMenu(self.top_frame, self.variable, *self.type_choices, style="Bold.TButton") self.type_options.config(width=int(BUTTON_WIDTH / 2)) self.type_options.grid(row=DROP_DOWN_ROW, column=0) self.save_type_button = Button(self.top_frame, text='Save Type', command=self.save_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.save_type_button.grid(row=SAVE_TYPE_ROW, column=1, sticky=tk.W + tk.E) self.deselect_all_button = Button(self.top_frame, text='Deselect All', command=self.deselect_all, width=BUTTON_WIDTH, style="Bold.TButton") self.deselect_all_button.grid(row=DESELECT_ALL_ROW, columnspan=2, sticky=tk.W + tk.E) self.select_all_button = Button(self.top_frame, text='Select All', command=self.select_all, width=BUTTON_WIDTH, style="Bold.TButton") self.select_all_button.grid(row=SELECT_ALL_ROW, columnspan=2, sticky=tk.W + tk.E) self.draw_poly_button = Button(self.top_frame, text='Draw Poly', command=self.draw_poly_func, width=BUTTON_WIDTH, style="Bold.TButton") self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.draw_rect_button = Button(self.top_frame, text='Draw Rectangle', command=self.draw_rect_func, width=BUTTON_WIDTH, style="Bold.TButton") self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) self.delete_all_button = Button(self.top_frame, text='Delete All', command=self.delete_all, width=BUTTON_WIDTH, style="Bold.TButton") self.save_poly_button = Button(self.top_frame, text='Save Poly', command=self.save_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.discard_poly_button = Button(self.top_frame, text='Discard Poly', command=self.discard_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.save_rect_button = Button(self.top_frame, text='Save Rect', command=self.save_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.discard_rect_button = Button(self.top_frame, text='Discard Rect', command=self.discard_drawing, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.show_type_button = Button(self.top_frame, text='Show Type', command=self.show_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.show_type_button.grid(row=SHOW_TYPE_ROW, column=0, columnspan=1, sticky=tk.W + tk.E) self.hide_type_button = Button(self.top_frame, text='Hide Type', command=self.hide_type, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.hide_type_button.grid(row=HIDE_TYPE_ROW, columnspan=1, column=1, sticky=tk.W + tk.E) self.make_tight_button = Button(self.top_frame, text='Make Tight', command=self.make_tight, width=int(BUTTON_WIDTH / 2), style="Bold.TButton") self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, column=0, sticky=tk.W + tk.E) self.threshold_scale = Scale(self.top_frame, from_=0, to=255, orient=HORIZONTAL, width=int(BUTTON_WIDTH / 2), label="Binary Threshold") self.threshold_scale.set(128) self.threshold_scale.grid(row=THRESHOLD_ROW, columnspan=2, column=0, sticky=tk.W + tk.E) self.tight_save_button = Button(self.top_frame, text='Accept Tight', command=self.save_tight) self.tight_discard_button = Button(self.top_frame, text='Discard Tight', command=self.discard_tight) self.canvas = Canvas(self.bottom_frame, width=INIT_WIDTH - BUTTON_WIDTH, height=INIT_HEIGHT, borderwidth=1) self.image_name = None #self.image_path = os.path.join('imgs','img1.jpg') self.image_dir = None self.images_in_dir = None self.curr_idx = None self.img_cnv = None #self.img_cnv = ImageOnCanvas(self.root,self.canvas,self.image_path) self.drawing_obj = None self.tight_box_obj = None self.left_frame.pack(side=tk.LEFT) self.top_frame1.pack(side=tk.TOP) self.top_frame.pack(side=tk.BOTTOM) self.bottom_frame.pack(side=tk.LEFT) self.canvas.pack() self.hide_buttons() self.load_image_directory_button.config(state="normal") def save_tight(self): self.tight_box_obj.save_tight_box() self.tight_save_button.grid_forget() self.tight_discard_button.grid_forget() self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, sticky=tk.W + tk.E) self.show_buttons() self.tight_box_obj = None def discard_tight(self): self.tight_box_obj.discard_tight_box() self.tight_save_button.grid_forget() self.tight_discard_button.grid_forget() self.make_tight_button.grid(row=MAKE_TIGHT_ROW, columnspan=2, sticky=tk.W + tk.E) self.show_buttons() self.tight_box_obj = None def show_type(self): for poly in self.img_cnv.polygons: if poly.select_poly: poly.show_type() def hide_type(self): for poly in self.img_cnv.polygons: poly.unshow_type() def hide_buttons(self): self.load_image_directory_button.config(state=tk.DISABLED) self.save_image_button.config(state=tk.DISABLED) self.delete_poly_button.config(state=tk.DISABLED) self.save_type_button.config(state=tk.DISABLED) self.deselect_all_button.config(state=tk.DISABLED) self.select_all_button.config(state=tk.DISABLED) self.delete_all_button.config(state=tk.DISABLED) self.show_type_button.config(state=tk.DISABLED) self.hide_type_button.config(state=tk.DISABLED) self.make_tight_button.config(state=tk.DISABLED) def show_buttons(self): self.load_image_directory_button.config(state="normal") self.save_image_button.config(state="normal") self.delete_poly_button.config(state="normal") self.save_type_button.config(state="normal") self.deselect_all_button.config(state="normal") self.select_all_button.config(state="normal") self.delete_all_button.config(state="normal") self.show_type_button.config(state="normal") self.hide_type_button.config(state="normal") self.draw_poly_button.config(state="normal") self.draw_rect_button.config(state="normal") self.make_tight_button.config(state="normal") def select_all(self): for poly in self.img_cnv.polygons: poly.select_polygon() def deselect_all(self): self.hide_type() for poly in self.img_cnv.polygons: poly.deselect_poly() def delete_all(self): result = messagebox.askyesno("Confirm Delete All", "Delete All Annotations?") if not result: return self.select_all() self.delete_selected() #self.img_cnv.polygons_mutex.acquire() #for poly in self.img_cnv.polygons: # poly.delete_self() #self.img_cnv.polygons_mutex.release() def save_type(self): selected_option = self.variable.get() self.img_cnv.polygons_mutex.acquire() for poly in self.img_cnv.polygons: if poly.select_poly == True: if selected_option == "None": poly.poly_type = None else: poly.poly_type = selected_option #poly.unshow_type() #poly.show_type() self.img_cnv.polygons_mutex.release() self.variable.set(self.type_choices[0]) #self.deselect_all() def load_new_img(self): self.canvas.delete('all') self.img_cnv = None path = os.path.join(self.image_dir, self.image_name) self.img_cnv = ImageOnCanvas(self.root, self.canvas, path) logger("LOADED: " + self.img_cnv.image_path) def load_directory(self): while True: selection = filedialog.askdirectory() if selection == () or selection == '': return self.root.directory = selection self.image_dir = self.root.directory file_names = os.listdir(self.image_dir) self.images_in_dir = [] self.curr_idx = None self.image_name = None for name in file_names: if name.split('.')[-1] in self.supported_formats: self.images_in_dir.append(name) if len(self.images_in_dir) == 0: self.pop_up("No supported images in the selected directory") else: break self.show_buttons() self.next_img() def pop_up(self, text): top = Toplevel() top.title("ERROR") msg = Message(top, text=text) msg.pack() button = Button(top, text="Dismiss", command=top.destroy) button.pack() def next_img(self): if self.curr_idx == None: self.curr_idx = -1 self.curr_idx = self.curr_idx + 1 if self.curr_idx >= len(self.images_in_dir): self.pop_up("Done with Images in this directory") self.curr_idx = self.curr_idx - 1 return if self.curr_idx > 0: self.prev_img_button.config(state="normal") self.image_name = self.images_in_dir[self.curr_idx] self.load_new_img() self.root.title("Form Labeller - " + self.image_name + "(" + str(self.curr_idx + 1) + "/" + str(len(self.images_in_dir)) + ")") def previous_img(self): if self.curr_idx == 1: self.curr_idx = -1 self.prev_img_button.config(state=tk.DISABLED) else: self.curr_idx = self.curr_idx - 2 self.next_img() def delete_selected(self): to_be_deleted = [] for i, poly in enumerate(self.img_cnv.polygons): if poly.select_poly == True: poly.delete_self() to_be_deleted.append(i) j = 0 for idx in to_be_deleted: self.img_cnv.polygons.pop(idx - j) self.img_cnv.bbs.pop(idx - j) self.img_cnv.poly_type.pop(idx - j) j = j + 1 def start_gui(self): self.root.mainloop() def saver(self): logger("Saving: " + self.img_cnv.image_path) self.save_image_button.config(state=tk.DISABLED) self.img_cnv.save_json(self.root.directory) self.save_image_button.config(state="normal") def draw_poly_func(self): self.deselect_all() self.img_cnv.drawing_polygon = True self.draw_poly_button.grid_forget() self.save_poly_button.grid(row=DRAW_POLY_ROW, column=0, sticky=tk.W + tk.E) self.discard_poly_button.grid(row=DRAW_POLY_ROW, column=1, sticky=tk.W + tk.E) self.hide_buttons() self.draw_rect_button.config(state=tk.DISABLED) self.drawing_obj = DrawPoly(self.bottom_frame, self.canvas, self.img_cnv, RADIUS) def draw_rect_func(self): self.deselect_all() self.img_cnv.drawing_polygon = True self.draw_rect_button.grid_forget() self.save_rect_button.grid(row=DRAW_RECT_ROW, column=0, sticky=tk.W + tk.E) self.discard_rect_button.grid(row=DRAW_RECT_ROW, column=1, sticky=tk.W + tk.E) self.hide_buttons() self.draw_poly_button.config(state=tk.DISABLED) self.drawing_obj = DrawRect(self.bottom_frame, self.canvas, self.img_cnv, RADIUS) def save_drawing(self): self.show_buttons() self.img_cnv.drawing_polygon = False new_poly_pts = self.drawing_obj.pt_coords print("Trying to save polygon with pts:", str(new_poly_pts)) for pt in self.drawing_obj.points: self.canvas.delete(pt) if self.img_cnv.scale_factor != None: for i in range(len(new_poly_pts)): for j in range(2): new_poly_pts[i][ j] = new_poly_pts[i][j] / self.img_cnv.scale_factor self.img_cnv.add_poly(new_poly_pts) #self.img_cnv.bbs.append(new_poly_pts) #self.img_cnv.draw_bbs([self.img_cnv.bbs[-1]]) #debug (1, str(type(self.drawing_obj))) if isinstance(self.drawing_obj, DrawRect): self.save_rect_button.grid_forget() self.discard_rect_button.grid_forget() self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) elif isinstance(self.drawing_obj, DrawPoly): self.save_poly_button.grid_forget() self.discard_poly_button.grid_forget() self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.drawing_obj.delete_self() self.drawing_obj = None def discard_drawing(self): self.show_buttons() self.img_cnv.drawing_polygon = False #for pt in self.drawing_obj.points: # self.canvas.delete(pt) self.drawing_obj.delete_self() if isinstance(self.drawing_obj, DrawRect): self.save_rect_button.grid_forget() self.discard_rect_button.grid_forget() self.draw_rect_button.grid(row=DRAW_RECT_ROW, columnspan=2, sticky=tk.W + tk.E) elif isinstance(self.drawing_obj, DrawPoly): self.save_poly_button.grid_forget() self.discard_poly_button.grid_forget() self.draw_poly_button.grid(row=DRAW_POLY_ROW, columnspan=2, sticky=tk.W + tk.E) self.drawing_obj = None def make_tight(self): self.hide_buttons() self.tight_box_obj = TightBox(self.root, self.img_cnv, self.threshold_scale.get()) self.tight_box_obj.tight_box() self.make_tight_button.grid_forget() self.tight_save_button.grid(row=MAKE_TIGHT_ROW, column=0, columnspan=1, sticky=tk.W + tk.E) self.tight_discard_button.grid(row=MAKE_TIGHT_ROW, column=1, columnspan=1, sticky=tk.W + tk.E)
class CategoryManager(Frame): """Category manager for the sticky notes.""" def __init__(self, master, app, **kwargs): """Create category manager.""" Frame.__init__(self, master, padding=4, **kwargs) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) self.app = app self.style = Style(self) self.style.theme_use("clam") self.im_plus = PhotoImage(file=IM_PLUS) self.im_delete = PhotoImage(file=IM_DELETE) # --- Default category self.frame_def_cat = Frame(self) self.default_category = StringVar( self.frame_def_cat, CONFIG.get("General", "default_category").capitalize()) Label(self.frame_def_cat, text=_("Default category ")).grid(row=0, column=0, sticky="e", padx=(4, 0)) self.categories = CONFIG.options("Categories") self.categories.sort() categories = [cat.capitalize() for cat in self.categories] self.def_cat_menu = OptionMenu( self.frame_def_cat, self.default_category, CONFIG.get("General", "default_category").capitalize(), *categories) optionmenu_patch(self.def_cat_menu, self.default_category) self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4) # --- Category colors, names ... style = Style(self) style.configure('txt.TFrame', relief='ridge', border=2) bg = style.lookup('TFrame', 'background') frame = Frame(self, style='txt.TFrame', padding=1) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) txt = Text(frame, width=1, height=1, bg=bg, relief='flat', highlightthickness=0, padx=6, pady=6, cursor='arrow') scroll_x = AutoScrollbar(frame, orient='horizontal', command=txt.xview) scroll_y = AutoScrollbar(frame, orient='vertical', command=txt.yview) txt.configure(xscrollcommand=scroll_x.set, yscrollcommand=scroll_y.set) txt.grid(row=0, column=0, sticky='ewns') scroll_x.grid(row=1, column=0, sticky='ew') scroll_y.grid(row=0, column=1, sticky='ns') self.frame_cat = Frame(txt) txt.window_create('1.0', window=self.frame_cat) txt.configure(state='disabled') self.colors = list(COLORS.keys()) self.colors.sort() self.images = [] self.cat_colors = {} self.cat_labels = {} self.cat_menus = {} self.cat_buttons = {} for i, cat in enumerate(self.categories): self.cat_labels[cat] = Label(self.frame_cat, text="%s" % cat.capitalize(), anchor='e') self.cat_labels[cat].grid(row=i + 2, column=0, sticky="ew", padx=2) self.cat_labels[cat].bind('<Double-Button-1>', self.change_name) self.cat_colors[cat] = StringVar(self) color = CONFIG.get("Categories", cat) self.cat_menus[cat] = OptionMenu(self.frame_cat, self.cat_colors[cat], INV_COLORS[color], *self.colors, command=lambda color, c=cat: self. change_menubutton_color(color, c), style="%s.TMenubutton" % cat) optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat]) self.style.configure("%s.TMenubutton" % cat, background=color) self.cat_menus[cat].grid(row=i + 2, column=1, sticky="w", padx=4, pady=4) self.cat_buttons[cat] = Button( self.frame_cat, image=self.im_delete, padding=0, command=lambda c=cat: self.del_cat(c)) self.cat_buttons[cat].grid(row=i + 2, column=2, padx=4, pady=4, sticky='ns') if len(self.categories) == 1: self.cat_buttons[self.categories[0]].configure(state="disabled") # --- placement self.frame_def_cat.grid(row=0, column=0, sticky="eswn", pady=4) frame.grid(row=1, column=0, sticky="eswn") Button(self, image=self.im_plus, command=self.add_cat).grid(row=2, column=0, sticky='w', pady=8) def change_name(self, event): """Change category name.""" def ok(event): cats = [l.cget('text').lower() for l in self.cat_labels.values()] cat = name.get().strip().lower() if cat and cat not in cats: label.configure(text=cat.capitalize()) if old_cat == self.default_category.get(): self.default_category.set(cat.capitalize()) self.update_def_cat_menu() name.destroy() label = event.widget old_cat = label.cget('text') name = Entry(self, justify='center') name.insert(0, label.cget('text')) name.place(in_=label, relx=0, rely=0, anchor='nw', relwidth=1, relheight=1) name.bind('<FocusOut>', lambda e: name.destroy()) name.bind('<Escape>', lambda e: name.destroy()) name.bind('<Return>', ok) name.selection_range(0, 'end') name.focus_set() def get_color(self, category): """Return color of category.""" return self.cat_colors[category].get() def get_name(self, category): return self.cat_labels[category].cget('text').lower() def change_menubutton_color(self, color, cat): """ Change the color of the menubutton of the category cat when its default color is changed. """ self.style.configure("%s.TMenubutton" % cat, background=COLORS[color]) def del_cat(self, category): """Remove category.""" rep = askyesnocancel( _("Question"), _("Do you want to delete all notes belonging to \ the category %(category)s? If you answer 'No', the category will be deleted but \ the notes will belong to the default category. Be careful, the change will take \ effect immediately and cannot be undone.") % {"category": category}) if rep is not None: del (self.cat_colors[category]) self.cat_buttons[category].grid_forget() del (self.cat_buttons[category]) self.cat_labels[category].grid_forget() cat = self.cat_labels[category].cget('text') del (self.cat_labels[category]) self.cat_menus[category].grid_forget() del (self.cat_menus[category]) self.categories.remove(category) CONFIG.remove_option("Categories", category) if self.default_category.get() == cat: default = list(self.cat_labels.values())[0].cget('text') self.default_category.set(default) CONFIG.set("General", "default_category", default.lower()) self.update_def_cat_menu() if len(self.categories) == 1: self.cat_buttons[self.categories[0]].configure( state="disabled") if rep: self.app.delete_cat(category) self.app.update_notes() self.app.update_menu() save_config() def update_def_cat_menu(self): """Update default caregory menu.""" self.def_cat_menu.destroy() categories = [l.cget('text') for l in self.cat_labels.values()] self.def_cat_menu = OptionMenu(self.frame_def_cat, self.default_category, None, *categories) optionmenu_patch(self.def_cat_menu, self.default_category) self.def_cat_menu.grid(row=0, column=1, sticky="w", padx=4, pady=4) def add_cat(self): """Add a category.""" top = Toplevel(self, class_='MyNotes') top.transient(self) top.grab_set() top.resizable(False, False) top.title(_("New Category")) def valide(event=None): cats = [l.cget('text').lower() for l in self.cat_labels.values()] cat = name.get().strip().lower() if cat and cat not in cats: c, i = self.frame_cat.grid_size() self.cat_labels[cat] = Label(self.frame_cat, text="%s" % cat.capitalize()) self.cat_labels[cat].grid(row=i, column=0, sticky="e") self.cat_colors[cat] = StringVar(self, _("Yellow")) self.cat_menus[cat] = OptionMenu( self.frame_cat, self.cat_colors[cat], _("Yellow"), *self.colors, command=lambda color, c=cat: self.change_menubutton_color( color, c), style="%s.TMenubutton" % cat) self.style.configure("%s.TMenubutton" % cat, background=COLORS[_("Yellow")]) optionmenu_patch(self.cat_menus[cat], self.cat_colors[cat]) self.cat_menus[cat].grid(row=i, column=1, padx=4, pady=4) self.cat_buttons[cat] = Button( self.frame_cat, image=self.im_delete, padding=0, command=lambda c=cat: self.del_cat(c)) self.cat_buttons[cat].grid(row=i, column=2, padx=4, pady=4, sticky='ns') self.cat_buttons[self.categories[0]].configure(state="normal") self.categories.append(cat) self.categories.sort() self.update_def_cat_menu() top.destroy() name = Entry(top, justify="center") name.grid(row=0, column=0, columnspan=2, sticky="ew") name.bind("<Return>", valide) name.bind("<Escape>", lambda e: top.destroy()) name.focus_set() Button(top, text="Ok", command=valide).grid(row=1, column=0, sticky="nswe") Button(top, text=_("Cancel"), command=top.destroy).grid(row=1, column=1, sticky="nswe")