Exemplo n.º 1
0
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()
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
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()
Exemplo n.º 6
0
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!')
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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)
Exemplo n.º 11
0
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'
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
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()
Exemplo n.º 14
0
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.")
Exemplo n.º 15
0
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))
Exemplo n.º 16
0
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()
Exemplo n.º 17
0
#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)
Exemplo n.º 18
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
Exemplo n.º 19
0
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")
Exemplo n.º 20
0
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."
Exemplo n.º 21
0
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")
Exemplo n.º 22
0
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)
Exemplo n.º 23
0

#===========================================
#        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)
Exemplo n.º 24
0
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)
Exemplo n.º 25
0
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")