Exemplo n.º 1
0
class Liste(Frame):
    def __init__(self, parent, utilisateurs):
        Frame.__init__(self, parent)
        self.parent = parent

        self.Liste_users = utilisateurs

        self.Liste = Listbox(self.parent, relief='sunken', bg='lightgrey')

        self.afficher_liste()

        self.Liste.pack(expand=1, fill=BOTH)
        self.pack(side=RIGHT, fill=BOTH, expand=1)

    def afficher_liste(self):
        self.Liste.delete(0, END)

        for user in self.Liste_users:
            self.Liste.insert('end', user.pseudo)
            self.Liste.itemconfig('end', foreground=user.couleur)

    def maj_liste(self, user, commande='ajouter'):
        if commande == 'ajouter':
            self.Liste_users.append(Utilisateur(user))
            self.Liste_users.sort(key=lambda x: x.pseudo)
        elif commande == 'enlever':
            try:
                for k in self.Liste_users:
                    if user == k.pseudo:
                        self.Liste_users.remove(k)
                        break
            except KeyError:
                print("L'utilisateur {} n'est pas dans la liste.".format(user))

        self.afficher_liste()
Exemplo n.º 2
0
class liste_mots:
    """Définit un cadre contenant une liste de mot avec un ascenseur"""
    def __init__(self,parent,titre,compare):
        police_mots=font.Font(parent, size=12, family='Courier')
        self.cadre = LabelFrame(parent, borderwidth=2,
                                relief=GROOVE,text=titre)
        self.ascenseur=Scrollbar(self.cadre,orient=VERTICAL)
        self.mots=Listbox(self.cadre, font=police_mots, width=LARGEUR_LISTE_MOTS,yscrollcommand = self.ascenseur.set )
        self.mots.bind('<<ListboxSelect>>', self.selection)
        self.mots.grid(column=0,row=0)
        self.ascenseur.grid(column=1,row=0,sticky=S+N)
        self.ascenseur.config( command = self.mots.yview )
        self.liste_mots=[]
        self.compare=compare
    def ajoute_mot_couleur(self,mot,couleur):
        fin=self.mots.size()
        self.mots.insert(fin,mot)
        self.mots.itemconfig(fin,fg=couleur)
        self.liste_mots.append(mot)
    def selection(self,e):
        mot=self.liste_mots[self.mots.curselection()[0]]
        self.compare.modifie_mot1(mot)
        self.parent.infos.delete("0.0",END)
        valeur=self.parent.dict_moyennes[mot]
        texte="Selon ce modèle, le mot '"+mot+"' a été lu en moyenne "+str(round(valeur,NB_DECIMALES))+ "fois par un élève de ce profil au cours de l'année écoulée."
        self.parent.infos.insert(END,texte)
Exemplo n.º 3
0
class App:

    WIDTH = 600
    HEIGHT = 800

    def __init__(self, root, funcs):
        self.root = root
        self.root.title("Plotki Migotki")
        self.root.geometry("%dx%d%+d%+d" % (App.WIDTH, App.HEIGHT, 0, 0))
        self.main_frame = Frame(root, width=App.WIDTH, height=App.HEIGHT)
        self.main_frame.pack_propagate(0)
        self.main_frame.pack()
        self.list_map = funcs
        self.listbox = Listbox(self.main_frame, height=4, width=15, selectbackground="orange")
        for ix, (entry, _f) in enumerate(self.list_map):
            plot_type, title = entry
            self.listbox.insert(ix, title)
            if plot_type == BARCHART:
                self.listbox.itemconfig(ix, bg='green')
            elif plot_type == BOXPLOT:
                self.listbox.itemconfig(ix, bg='yellow')
            elif plot_type == SCATTERPLOT:
                self.listbox.itemconfig(ix, bg='grey')
            elif plot_type == HISTOGRAM:
                self.listbox.itemconfig(ix, bg='magenta')
        self.listbox.bind("<Double-Button-1>", self.call_back)
        self.listbox.bind("<Return>", self.call_back)
        self.listbox.pack(expand=1, fill=tk.BOTH)

    def call_back(self, event):
        zones = self.listbox.curselection()
        assert len(zones) == 1
        ix = zones[0]
        ix, cb = self.list_map[ix]
        cb()
Exemplo n.º 4
0
class ChatWindow(MessageSubscriber):
    def __init__(self, root, username, sender):
        self.frame = Frame(root)
        self.username = username
        self.sender = sender
        self.put_message_lock = Lock()

        Grid.columnconfigure(self.frame, 0, weight=2)
        Grid.columnconfigure(self.frame, 1, weight=0)
        Grid.rowconfigure(self.frame, 0, weight=2)
        Grid.rowconfigure(self.frame, 1, weight=0)

        self.scrollbar = Scrollbar(self.frame)
        self.messages = Listbox(self.frame,
                                yscrollcommand=self.scrollbar.set,
                                height=15,
                                width=50)
        self.scrollbar.grid(row=0, column=1, sticky=N + S)
        self.messages.grid(row=0, column=0, sticky=N + S + W + E)
        self.scrollbar.config(command=self.messages.yview)

        self.input_user = StringVar()
        self.input_field = Entry(self.frame, text=self.input_user)
        self.input_field.grid(row=1, column=0, sticky=W + E + S)

        self.send_button = Button(self.frame,
                                  text="Send",
                                  command=self.send_message)
        self.send_button.grid(row=1, column=1, sticky=S)

        self.input_field.bind("<Return>", lambda key: self.send_message())
        self.frame.pack(fill=BOTH, expand=YES)
        self.input_field.focus()

    def send_message(self):
        input_val = self.input_field.get()
        date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        if input_val == "":
            return
        if self.sender(input_val, date, self.username):
            self.input_user.set("")

    def put_message_in_chat(self, message, date, username, color="red"):
        with self.put_message_lock:
            self.messages.insert(END, date + "  " + username + ": " + message)
            self.messages.itemconfig(END, {"fg": color})
            self.messages.yview(END)

    def receive_message(self, text, date, name):
        self.put_message_in_chat(text, date, name)
Exemplo n.º 5
0
 def show_items(self, list_of_items: list, target_box: Listbox,
                check_original: bool):
     target_box.delete(0, END)
     index = 0
     for item in list_of_items:
         target_box.insert(END, item)
         if check_original and not self.files_map.get(item):
             self.source_files_box.itemconfig(index, {'fg': 'gray50'})
             target_box.itemconfig(index, {'fg': 'red'})
         elif check_original and self.files_map.get(item):
             self.source_files_box.itemconfig(index, {'fg': 'black'})
             target_box.itemconfig(index, {'fg': 'black'})
         index += 1
     scroll_position = ('moveto', self.scroll_bar_position[0])
     self.source_files_box.yview(*scroll_position)
     self.result_files_box.yview(*scroll_position)
Exemplo n.º 6
0
class liste_mots:
    """Définit un cadre contenant une liste de mot avec un ascenseur"""
    def __init__(self, parent, titre):
        police_mots = font.Font(parent, size=12, family='Courier')
        self.cadre = LabelFrame(parent,
                                borderwidth=2,
                                relief=GROOVE,
                                text=titre)
        self.ascenseur = Scrollbar(self.cadre, orient=VERTICAL)
        self.mots = Listbox(self.cadre,
                            font=police_mots,
                            width=LARGEUR_LISTE_MOTS,
                            yscrollcommand=self.ascenseur.set)
        self.mots.grid(column=0, row=0)
        self.ascenseur.grid(column=1, row=0, sticky=S + N)
        self.ascenseur.config(command=self.mots.yview)

    def ajoute_mot_couleur(self, mot, couleur):
        fin = self.mots.size()
        self.mots.insert(fin, mot)
        self.mots.itemconfig(fin, fg=couleur)
Exemplo n.º 7
0
class HistoryWindow:
    MAX_QUERY_SIZE = 64

    def __init__(self, parent, win, hist_dict):
        self.window = win
        self.parent_window = parent
        self.hist_dict = hist_dict
        self.window.title("Full history")
        # self.window.resizable(False, False)

        frm_top = Frame(win)
        frm_bottom = Frame(win)

        self.btn_test = Button(frm_top, text="Test", command=self.on_test)
        self.btn_test.grid(row=1, column=1, sticky=W + E)

        self.progress = ttk.Progressbar(frm_top,
                                        orient=HORIZONTAL,
                                        length=30,
                                        mode='indeterminate')

        self.btn_test_next = Button(frm_top,
                                    text="Test Next",
                                    command=self.on_test_next)
        self.btn_test_next.grid(row=1, column=4, sticky=W + E)

        self.search = StringVar()
        self.search.trace(
            "w", lambda name, index, mode, sv=self.search: self.on_search(sv))
        self.entry_search = Entry(frm_top, textvariable=self.search, width=52)
        self.entry_search.grid(row=2, column=1, columnspan=3, sticky=W + E)

        self.btn_clear = Button(frm_top, text="Clear", command=self.on_clear)
        self.btn_clear.grid(row=2, column=4, sticky=W + E)

        self.list_box = Listbox(frm_bottom,
                                width=60,
                                height=40,
                                selectmode=SINGLE)
        self.list_box.pack(side=LEFT, fill=BOTH, expand=1)
        scroll = Scrollbar(frm_bottom,
                           command=self.list_box.yview,
                           orient=VERTICAL)
        scroll.pack(side=RIGHT, fill=Y)
        self.list_box.config(yscrollcommand=scroll.set)
        self.list_box.bind('<<ListboxSelect>>', self.on_listbox_select)

        frm_top.pack()
        frm_bottom.pack()

        self.window.bind("<FocusIn>", self.focus_callback)
        self.window.protocol("WM_DELETE_WINDOW", self.on_close)

        self.test_online_start = 0

        self.fill_list_box()

    def on_clear(self):
        self.search.set("")
        self.on_search(self.search)

    def on_search(self, search):
        query = search.get().strip().lower()
        if len(query) < 2:
            self.fill_list_box()
            return

        self.list_box.delete(0, END)
        search_results = []
        for key in self.hist_dict:
            pos = key.lower().find(query)
            if pos == -1:
                continue

            search_results.append((key, pos))

        search_results.sort(key=lambda x: x[1])
        self.list_box.insert(END, *[x[0] for x in search_results])

    def fill_list_box(self):
        self.list_box.delete(0, END)
        hist = sorted(self.hist_dict.items(), key=lambda x: x[1], reverse=True)
        self.list_box.insert(END, *[x[0] for x in hist])

    def on_listbox_select(self, event):
        w = event.widget
        selected = w.curselection()
        if len(selected) == 0:
            return

        index = selected[0]
        value = w.get(index)
        self.parent_window.load_model(value, True)

    def lift(self):
        self.window.lift()

    def on_close(self):
        self.parent_window.hist_window = None
        self.window.update_idletasks()
        self.window.destroy()

    def focus_callback(self, event):
        self.entry_search.selection_range(0, END)
        root.lift()

    def test_online(self, model_list):
        global root

        update_models_bps(model_list, 1)
        root.after_idle(self.update_listbox, model_list)

    def update_listbox(self, model_list):
        for model in model_list:
            self.list_box.itemconfig(
                model.pos, {'fg': 'red' if model.is_online else 'blue'})
        self.set_controls_state(NORMAL)

    def on_test(self):
        self.test_online_start = 0
        for i in range(self.list_box.size()):
            self.list_box.itemconfig(i, {'fg': 'black'})

        self.on_test_next()

    def on_test_next(self):
        items = self.list_box.get(
            self.test_online_start,
            self.test_online_start + HistoryWindow.MAX_QUERY_SIZE - 1)

        model_list = []
        for i, name in zip(
                range(self.test_online_start,
                      self.test_online_start + len(items)), items):
            model_list.append(Model(i, name))

        self.test_online_start += HistoryWindow.MAX_QUERY_SIZE
        self.set_controls_state(DISABLED)

        executor.submit(self.test_online, model_list)

    def set_controls_state(self, state):
        self.btn_test.config(state=state)
        self.btn_test_next.config(state=state)
        self.btn_clear.config(state=state)
        self.entry_search.config(state=state)

        if state == DISABLED:
            self.progress.grid(row=1, column=2, columnspan=2, sticky=W + E)
            self.progress.start()
        else:
            self.progress.grid_forget()
            self.progress.stop()
Exemplo n.º 8
0
class Home(TkPage):
    Name = 'Home' #name of the class (attributes)
    Font = lambda Size: ('Courier', Size) #font of the page

    def __init__(self, Parent, *args, **kwargs):
        super().__init__(Parent, *args, **kwargs) #constructor of super class

        self.Songs = [Song.replace('.mid', '') for Song in DirList('Songs') if Song.endswith('.mid')] #mappable songs
        self.MappedSongs = [Song for Song in DirList('MappedSongs') if Song.endswith('.cmid')] #mapped and compiled song
        self.Playing = ThreadEvent() #pause state
        self.Stop = ThreadEvent() #playing state
        self.Stop.set()

        TopLabel = Label(self, text = 'Genshin Lyre Player', font= Home.Font(24), bd = 10) #top label with a title for the page
        TopLabel.place(anchor= 'n', relx= 0.5, rely = 0.015, relwidth = 1, relheight=0.15) #placing the label

        self.ItemList = ListBox(self) #item list of the song
        for Index,Item in enumerate(self.MappedSongs): #for loop for every compiled comiled song
            self.ItemList.insert(Index, Item) #indexing the song in the list
            self.ItemList.itemconfig(Index, {'bg' : '#C2C2C2'}) #background of itemlist
        self.ItemList.place(anchor= 'n', relx= 0.5, rely = 0.19, relwidth = 1, relheight = 0.46) #placing the item list

        #RefreshLogo = Photo(file = 'Res/Refresh.png') #logo of refresh button (not showing at the moment)
        self.RefreshButton = Button\
        (
            self,
            text = 'Refresh',
            command = lambda : self.Refresh()
        ) #button to refresh the song list
        #self.RefreshButton.image = RefreshLogo ########
        self.RefreshButton.place(anchor= 'nw', relx = 0.01, rely = 0.7, relwidth = 0.18, relheight = 0.2) #placing the button

        self.StopButton = Button\
        (
            self,
            text = 'Stop',
            command = lambda : self.StopSong()
        )
        self.StopButton.place(anchor= 'nw', relx= 0.21, rely = 0.7, relwidth = 0.18, relheight = 0.2)

        #PlayLogo = Photo(file = 'Res/Play.png') #logo of play button (not showing at the moment)
        self.PlayButton = Button\
        (
            self,
            text = 'Play',
        )#button to play the song selected
        self.PlayButton.config\
        (
            command =\
            lambda:
            [
                Thread(target = self.PlayTrack, args = (Track,), name = f'{self.ItemList.get("active")}[{i}]', daemon = True).start()
                for i, Track in enumerate(self.LoadSong())
            ]#lambda: self.Play()
        )
        #self.PlayButton.image = PlayLogo ##########
        self.PlayButton.place(anchor= 'nw', relx= 0.41, rely = 0.7, relwidth = 0.18, relheight = 0.2) #placing the button

        #PauseLogo = Photo(file = '') #logo of the pause button
        self.PauseButton = Button\
        (
            self,
            text = 'Pause',
            command = lambda : self.PauseSong()
        ) #button to pause a song
        self.PauseButton.place(anchor= 'nw', relx= 0.61, rely = 0.7, relwidth = 0.18, relheight = 0.2) #placing the button

        self.CompileButton = Button\
        (
            self,
            text = 'Compilation\n     Screen',
            command = lambda : self.Compile(),
        )
        self.CompileButton.place(anchor = 'nw', relx= 0.81, rely = 0.7, relwidth = 0.18, relheight = 0.2) #placing the button

    def Refresh(self): #this function refresh the song list
        self.MappedSongs = [Song for Song in DirList('MappedSongs') if Song.endswith('.cmid')] #check the folder for the songs
        self.ItemList.delete('0','end') #delete every item of the list
        for Index, Item in enumerate(self.MappedSongs): #loop for every song in the folder
            self.ItemList.insert(Index, Item) #index the song in the item list
            self.ItemList.itemconfig(Index, {'bg' : '#C2C2C2'}) #background of the itemlist

    def Countdown(self): #this function create an initial countdown
        for i in range(3): #3...2...1
            print(3-i)
            self.after(1000)

    def LoadSong(self):
        self.PlayButton.state(['disabled']) #disable the play button (might cause some unexpected behaviours)
        Song = self.ItemList.get('active') #getting the selected song from the list
        self.Stop.clear() #reset the stop state
        self.Playing.set()

        with open('MappedSongs/' + Song, 'rb') as InputFile: #opening the compiled midi file
            Music = Load(InputFile) #load the searialized object

        self.Countdown() #initial countdown to give user time to switch to genshin

        return Music

    def PlayTrack(self, Part = None): #this (THREADED) function play a single part (track) of the selected song
        if Part == None:
            raise ValueError('Part cannot be None')
        else:
            print(f'{Identity()} ready')

        global Notes
        global DXCodes
        global NotesFlags
        Elements = len(Part) #keystrokes to execute
        Actual = 0 #element counter

        def PlayNote(Sound, Duration): #this function play a single note of the part
            NotesFlags[Sound] = False #make the resource unavailable for other threads (to avoid deadlock)
            PressKey(DXCodes[Notes[Sound]]) #press note-corresponding key
            Sleep(abs(Duration)) #wait the duration of the note
            ReleaseKey(DXCodes[Notes[Sound]]) #release note-corresponding key
            NotesFlags[Sound] = True #make the resource available for other threads

        def PlayChord(Sounds, Duration): # function play a single chord of the part
            #print(Duration)
            for Sound in Sounds: #for loop  to make every note of the chord unavailable for other threads (to avoid deadlock)
                NotesFlags[Sound] = False #lock single resource

            for Sound in Sounds: #for loop to press chord-corresponding keys
                PressKey(DXCodes[Notes[Sound]]) #press the note-corresponding key of the chord

            Sleep(abs(Duration)) #wait the duration of the notes

            for Sound in Sounds: #for loop to release chord-corresponding keys
                ReleaseKey(DXCodes[Notes[Sound]]) #release the note-corresponding key of the chord

            for Sound in Sounds:#for loop to make every note of the chord available for other threads
                NotesFlags[Sound] = True #unlock single resource

        while not self.Stop.is_set() and Actual < Elements:
            if IsPressed('ctrl+space'):
                if not PauseFunction.locked():
                    PauseFunction.acquire()
                    self.StopSong()
                    PauseFunction.release()
                break
            if IsPressed('shift'):
                print('resume trigger')
                Sleep(1)
                self.Playing.set()

            while self.Playing.is_set() and Actual < Elements:
                if IsPressed('ctrl+space'):
                    if not PauseFunction.locked():
                        PauseFunction.acquire()
                        self.StopSong()
                        PauseFunction.release()
                    break
                if IsPressed('shift'):
                    print('pause trigger')
                    Sleep(1)
                    self.Playing.clear()
                    break

                Counter = 0

                if Part[Actual]['Type'] == 'Note': #check if the element is a note
                    Duration = float(Part[Actual]['Duration'])
                    PartialDuration = Duration / 10 #duration splitted to check multiple times
                    Note = f'{Part[Actual]["Sound"]}{Part[Actual]["Octave"]}' #extract the note

                    if NotesFlags[Note] and IsMainAlive(): #check if the resource is available
                        PlayNote(Note, Duration) #if the reseourse plays the note at full duration
                    else: #if the resource is not available at the moment
                        while not NotesFlags[Note] or Counter < 10: #check if the note is still playable
                            Sleep(PartialDuration) #waiting the partial duration to check availability
                            Counter += 1 #increasing wastd times

                        if NotesFlags[Note] and Counter < 10: #check if the resource are available and the note is still playable
                            RemainingDuration = Duration - (PartialDuration * Counter) #calculate remaining duration
                            PlayNote(Note, RemainingDuration) #play the note at partial duration
                elif Part[Actual]['Type'] == 'Chord': # check if the element is a chord (multiple notes together)
                    NotesList = Part[Actual]['Sound'] #extract notes of the chord
                    Octaves = Part[Actual]['Octave'] #extract respective octaves of the notes
                    Chord = [f'{Note}{Octave}' for Note, Octave in zip(NotesList, Octaves)] # combine notes and octaves together
                    Duration = float(Part[Actual]['Duration'])
                    PartialDuration = Duration / 10 #duration splitted to check multiple times

                    if all([NotesFlags[Note] for Note in Chord]) and IsMainAlive(): #check if all the notes in the chord are available (otherwise the cord wouldn't make sense)
                        PlayChord(Chord, Duration) #play the chord at full duration
                    else:
                        while not all([NotesFlags[Note] for Note in Chord]): #check if the chord is stil playable
                            Sleep(PartialDuration) #waiting the partial duration to check availability
                            Counter += 1 #increasing wasted times

                        if all([NotesFlags[Note] for Note in Chord]) and IsMainAlive(): #check if the resources are available and the chors is still playable
                            RemainingDuration = Duration - (PartialDuration * Counter) #calculate remaining duration
                            PlayChord(Chord, RemainingDuration) #play the chord at partial duration
                elif Part[Actual]['Type'] == 'Rest': #check if the element is a rest
                    Duration = float(Part[Actual]['Duration'])
                    Sleep(abs(Duration)) #wait the rest

                Actual += 1 #increase the played notes

        Sleep(5)
        print(f'{Identity()} ended')

    def PauseSong(self): #this fucntion pause the song playing
        Sleep(2) #delay to get rid of function call besides the first
        if self.Playing.is_set(): #check if the song is playing
            print(f'{Identity()} is pausing')
            self.Playing.clear() #clear the playing state
        if not self.Playing.is_set(): #check if the song is not playing
            print(f'{Identity()} is resuming')
            self.Playing.set() #set the song as playing

    def StopSong(self): #this fucntion stop the song
        if not StopFunction.locked(): #check if the fucntion has called by multiple thread
            print('Stop called')
            Sleep(1)
            self.Stop.set() #set the stop state
            self.Playing.clear() #clear the playing state
            self.PlayButton.state(['!disabled']) #enable the play button
            self.PlayButton.state(['!pressed']) #reset the play button to the default state
            ReleaseResources() #release possible hanging resources

    def Compile(self): #this function switch to compilation screen
        GenshinLyrePlayer.Raise(CompilationScreen.Name)
Exemplo n.º 9
0
class FileChoice(object):
    def __init__(self,
                 master=None,
                 title=None,
                 prefix=None,
                 list=[],
                 start='',
                 ext="txt",
                 new=False):
        self.master = master
        self.value = None
        self.prefix = prefix
        self.list = list
        if prefix and start:
            self.start = relpath(start, prefix)
        else:
            self.start = start
        self.ext = ext
        self.new = new

        self.modalPane = Toplevel(self.master,
                                  highlightbackground=BGCOLOR,
                                  background=BGCOLOR)
        if master:
            logger.debug('winfo: {0}, {1}; {2}, {3}'.format(
                master.winfo_rootx(), type(master.winfo_rootx()),
                master.winfo_rooty(), type(master.winfo_rooty())))
            self.modalPane.geometry(
                "+%d+%d" %
                (master.winfo_rootx() + 50, master.winfo_rooty() + 50))

        self.modalPane.transient(self.master)
        self.modalPane.grab_set()

        self.modalPane.bind("<Return>", self._choose)
        self.modalPane.bind("<Escape>", self._cancel)

        if title:
            self.modalPane.title(title)

        if new:
            nameFrame = Frame(self.modalPane,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR)
            nameFrame.pack(side="top", padx=18, pady=2, fill="x")

            nameLabel = Label(nameFrame,
                              text=_("file:"),
                              bd=1,
                              relief="flat",
                              anchor="w",
                              padx=0,
                              pady=0,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR)
            nameLabel.pack(side="left")

            self.fileName = StringVar(self.modalPane)
            self.fileName.set("untitled.{0}".format(ext))
            self.fileName.trace_variable("w", self.onSelect)
            self.fname = Entry(nameFrame,
                               textvariable=self.fileName,
                               bd=1,
                               highlightbackground=BGCOLOR)
            self.fname.pack(side="left", fill="x", expand=1, padx=0, pady=0)
            self.fname.icursor(END)
            self.fname.bind("<Up>", self.cursorUp)
            self.fname.bind("<Down>", self.cursorDown)

        filterFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        filterFrame.pack(side="top", padx=18, pady=4, fill="x")

        filterLabel = Label(filterFrame,
                            text=_("filter:"),
                            bd=1,
                            relief="flat",
                            anchor="w",
                            padx=0,
                            pady=0,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        filterLabel.pack(side="left")

        self.filterValue = StringVar(self.modalPane)
        self.filterValue.set("")
        self.filterValue.trace_variable("w", self.setMatching)
        self.fltr = Entry(filterFrame,
                          textvariable=self.filterValue,
                          bd=1,
                          highlightbackground=BGCOLOR)
        self.fltr.pack(side="left", fill="x", expand=1, padx=0, pady=0)
        self.fltr.icursor(END)

        prefixFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        prefixFrame.pack(side="top", padx=8, pady=2, fill="x")

        self.prefixLabel = Label(prefixFrame,
                                 text=_("{0}:").format(prefix),
                                 bd=1,
                                 highlightbackground=BGCOLOR,
                                 background=BGCOLOR)
        self.prefixLabel.pack(side="left", expand=0, padx=0, pady=0)

        buttonFrame = Frame(self.modalPane,
                            highlightbackground=BGCOLOR,
                            background=BGCOLOR)
        buttonFrame.pack(side="bottom", padx=10, pady=2)

        chooseButton = Button(buttonFrame,
                              text="Choose",
                              command=self._choose,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR,
                              pady=2)
        chooseButton.pack(side="right", padx=10)

        cancelButton = Button(buttonFrame,
                              text="Cancel",
                              command=self._cancel,
                              highlightbackground=BGCOLOR,
                              background=BGCOLOR,
                              pady=2)
        cancelButton.pack(side="left")

        selectionFrame = Frame(self.modalPane,
                               highlightbackground=BGCOLOR,
                               background=BGCOLOR)
        selectionFrame.pack(side="bottom", padx=8, pady=2, fill="x")

        self.selectionValue = StringVar(self.modalPane)
        self.selectionValue.set("")
        self.selection = Label(selectionFrame,
                               textvariable=self.selectionValue,
                               bd=1,
                               highlightbackground=BGCOLOR,
                               background=BGCOLOR)
        self.selection.pack(side="left", fill="x", expand=1, padx=0, pady=0)

        listFrame = Frame(self.modalPane,
                          highlightbackground=BGCOLOR,
                          background=BGCOLOR,
                          width=40)
        listFrame.pack(side="top", fill="both", expand=1, padx=5, pady=2)

        scrollBar = Scrollbar(listFrame, width=8)
        scrollBar.pack(side="right", fill="y")
        self.listBox = Listbox(listFrame, selectmode=BROWSE, width=36)
        self.listBox.pack(side="left",
                          fill="both",
                          expand=1,
                          ipadx=4,
                          padx=2,
                          pady=0)
        self.listBox.bind('<<ListboxSelect>>', self.onSelect)
        self.listBox.bind("<Double-1>", self._choose)
        self.modalPane.bind("<Return>", self._choose)
        self.modalPane.bind("<Escape>", self._cancel)
        # self.modalPane.bind("<Up>", self.cursorUp)
        # self.modalPane.bind("<Down>", self.cursorDown)
        self.fltr.bind("<Up>", self.cursorUp)
        self.fltr.bind("<Down>", self.cursorDown)
        scrollBar.config(command=self.listBox.yview)
        self.listBox.config(yscrollcommand=scrollBar.set)
        self.setMatching()

    def ignore(self, e=None):
        return "break"

    def onSelect(self, *args):
        # Note here that Tkinter passes an event object to onselect()

        if self.listBox.curselection():
            firstIndex = self.listBox.curselection()[0]
            value = self.matches[int(firstIndex)]
            r = value[1]
            p = os.path.join(self.prefix, r)
            if self.new:
                if os.path.isfile(p):
                    p = os.path.split(p)[0]
                    r = os.path.split(r)[0]
                f = self.fileName.get()
                r = os.path.join(r, f)
                p = os.path.join(p, f)

            self.selectionValue.set(r)
            self.value = p
        return "break"

    def cursorUp(self, event=None):
        cursel = int(self.listBox.curselection()[0])
        newsel = max(0, cursel - 1)
        self.listBox.select_clear(cursel)
        self.listBox.select_set(newsel)
        self.listBox.see(newsel)
        self.onSelect()
        return "break"

    def cursorDown(self, event=None):
        cursel = int(self.listBox.curselection()[0])
        newsel = min(len(self.list) - 1, cursel + 1)
        self.listBox.select_clear(cursel)
        self.listBox.select_set(newsel)
        self.listBox.see(newsel)
        self.onSelect()
        return "break"

    def setMatching(self, *args):
        # disabled = "#BADEC3"
        # disabled = "#91CC9E"
        disabled = "#62B374"
        match = self.filterValue.get()
        if match:
            self.matches = matches = [
                x for x in self.list if x and match.lower() in x[1].lower()
            ]
        else:
            self.matches = matches = self.list
        self.listBox.delete(0, END)
        index = 0
        init_index = 0
        for item in matches:
            if type(item) is tuple:
                # only show the label
                # (label, value, disabled)FF
                self.listBox.insert(END, item[0])
                if self.new:
                    if not item[-1]:
                        self.listBox.itemconfig(index, fg=disabled)
                    else:
                        self.listBox.itemconfig(index, fg="blue")
                        if self.start and item[1] == self.start:
                            init_index = index
                else:
                    if item[-1]:
                        self.listBox.itemconfig(index, fg=disabled)
                    else:
                        self.listBox.itemconfig(index, fg="blue")
                        if self.start and item[1] == self.start:
                            init_index = index
            # elif files:
            else:
                self.listBox.insert(END, item)
            index += 1
        self.listBox.select_set(init_index)
        self.listBox.see(init_index)
        self.fltr.focus_set()
        self.onSelect()

    def _choose(self, event=None):
        try:
            if self.listBox.curselection():
                firstIndex = self.listBox.curselection()[0]
                if self.new:
                    if not self.value or os.path.isfile(self.value):
                        return
                else:
                    tup = self.matches[int(firstIndex)]
                    if tup[-1]:
                        return
                    self.value = os.path.join(self.prefix, tup[1])
            else:
                return
        except IndexError:
            self.value = None
        self.modalPane.destroy()

    def _cancel(self, event=None):
        self.value = None
        self.modalPane.destroy()

    def returnValue(self):
        self.master.wait_window(self.modalPane)
        return self.value
Exemplo n.º 10
0
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, background="#8080FF")
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("EQ GuildViewer 0.1")

        fontb = Font(size=12, weight="bold")

        # inicializo variables
        self.ant = None
        self.lastLine = 0
        self.name = ""

        # frame padre
        area = Frame(self)
        area.pack(side=BOTTOM, fill=BOTH, expand=1)

        areab = Frame(self)
        areab.pack(side=TOP, fill=BOTH, expand=1)

        # scroll players
        self.scrollbar2 = Scrollbar(areab, orient=VERTICAL)

        # construimos un menu con todos los nombres del diccionario y un boton
        self.refreshButton = Button(areab, text="""PARSEA!""", command=self.onRefresh, bd=2, relief="groove")
        self.listboxLogs = Listbox(
            areab, width=50, activestyle="none", highlightthickness=0, yscrollcommand=self.scrollbar2.set, relief=RIDGE
        )
        self.listboxLogs.pack(side=LEFT, fill=Y)
        self.scrollbar2.pack(side=LEFT, fill=Y)
        self.refreshButton.pack(side=LEFT, fill=BOTH, expand=1)

        for player in optionsDictionary:
            self.listboxLogs.insert(END, player)

        # scroll
        self.scrollbar = Scrollbar(area, orient=VERTICAL)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        # area1
        area1 = Frame(area)
        area1.pack(side=LEFT, fill=Y)

        lbl = Label(area1, text="Name")
        self.listbox = Listbox(
            area1, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none"
        )
        lbl.pack(side=TOP)
        self.listbox.pack(side=BOTTOM, fill=Y, expand=1)

        # area2
        area2 = Frame(area)
        area2.pack(side=LEFT, fill=Y)

        lbl2 = Label(area2, text="Level")
        self.listbox2 = Listbox(
            area2, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none"
        )
        lbl2.pack(side=TOP)
        self.listbox2.pack(side=BOTTOM, fill=Y, expand=1)

        # area3
        area3 = Frame(area)
        area3.pack(side=LEFT, fill=Y)

        lbl3 = Label(area3, text="Class")
        self.listbox3 = Listbox(
            area3, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none"
        )
        lbl3.pack(side=TOP)
        self.listbox3.pack(side=BOTTOM, fill=Y, expand=1)

        # area4
        area4 = Frame(area)
        area4.pack(side=LEFT, fill=Y)

        lbl4 = Label(area4, text="Race")
        self.listbox4 = Listbox(
            area4, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none"
        )
        lbl4.pack(side=TOP)
        self.listbox4.pack(side=BOTTOM, fill=Y, expand=1)

        # area3
        area5 = Frame(area)
        area5.pack(side=LEFT, fill=Y)

        lbl5 = Label(area5, text="Zone")
        self.listbox5 = Listbox(
            area5, yscrollcommand=self.scrollbar.set, font=fontb, relief=FLAT, highlightthickness=0, activestyle="none"
        )
        lbl5.pack(side=TOP)
        self.listbox5.pack(side=BOTTOM, fill=Y, expand=1)

        self.pack(fill=BOTH, expand=1)

        # config-scrollbar
        self.scrollbar.config(command=self.yview)
        self.scrollbar2["command"] = self.listboxLogs.yview

        # bindeos de acciones
        self.listbox.bind("<<ListboxSelect>>", self.onSelect)
        self.listbox.bind("<MouseWheel>", self.onTest)
        self.listbox2.bind("<<ListboxSelect>>", self.onSelect)
        self.listbox2.bind("<MouseWheel>", self.onTest)
        self.listbox3.bind("<<ListboxSelect>>", self.onSelect)
        self.listbox3.bind("<MouseWheel>", self.onTest)
        self.listbox4.bind("<<ListboxSelect>>", self.onSelect)
        self.listbox4.bind("<MouseWheel>", self.onTest)
        self.listbox5.bind("<<ListboxSelect>>", self.onSelect)
        self.listbox5.bind("<MouseWheel>", self.onTest)
        self.listboxLogs.bind("<<ListboxSelect>>", self.onSelectPlayer)

    # mostrar la barra de scroll
    def yview(self, *args):
        self.listbox.yview(*args)
        self.listbox2.yview(*args)
        self.listbox3.yview(*args)
        self.listbox4.yview(*args)
        self.listbox5.yview(*args)

    # accion de la rueda del raton
    def onTest(self, val):
        return "break"

    # seleccionar un elementos de una listbox
    def onSelect(self, val):
        try:
            if self.ant != None:
                self.listbox.itemconfig(self.ant, background="#FFFFFF")
                self.listbox2.itemconfig(self.ant, background="#FFFFFF")
                self.listbox3.itemconfig(self.ant, background="#FFFFFF")
                self.listbox4.itemconfig(self.ant, background="#FFFFFF")
                self.listbox5.itemconfig(self.ant, background="#FFFFFF")
            self.listbox.itemconfig(val.widget.curselection(), background="#C0C0C0")
            self.listbox2.itemconfig(val.widget.curselection(), background="#C0C0C0")
            self.listbox3.itemconfig(val.widget.curselection(), background="#C0C0C0")
            self.listbox4.itemconfig(val.widget.curselection(), background="#C0C0C0")
            self.listbox5.itemconfig(val.widget.curselection(), background="#C0C0C0")

            self.ant = val.widget.curselection()
        except:
            None
            # print('No hay valores')

    # dependiendo de que nombre se elija en el menu cargamos en lastLine la linea de ese nombre del diccionario
    def onSelectPlayer(self, val):
        try:
            self.name = val.widget.get(val.widget.curselection())
            self.lastLine = optionsDictionary[self.name]
            # print(self.name, ' ', self.lastLine)
        except:
            None
            # print('No hay valores')

    # recorremos el fichero log al clickar sobre el boton 'Refresh!'
    def onRefresh(self):
        if self.name != "":
            yes = False
            count = 0
            dictionary = {}
            dictionaryAuxiliar = {}

            stringLog = "../eqlog_" + str(self.name) + "_project1999.txt"
            with open(stringLog, "r") as log:
                for i in range(int(self.lastLine)):
                    next(log)
                    count = count + 1
                for line in log:
                    match = re.match("\[.*\] \[(.*) (.*)\] (.*) \((.*)\) <.*> ZONE: (.*)", line)
                    matchRole = re.match("\[.*\] \[(.*)\] (.*) <.*>", line)
                    matchToken = re.match("\[.*\] You say, 't0000'", line)
                    matchTokenI = re.match("\[.*\] You say, 't0001'", line)

                    if matchTokenI != None:
                        yes = True
                    elif match != None and yes:
                        dictionaryAuxiliar[match.group(3)] = (
                            match.group(1),
                            match.group(2),
                            match.group(4),
                            match.group(5),
                        )
                    elif matchRole != None and yes:
                        dictionaryAuxiliar[matchRole.group(2)] = [(matchRole.group(1))]
                    elif matchToken != None and yes:
                        dictionary = dictionaryAuxiliar.copy()
                        dictionaryAuxiliar.clear()
                        yes = False
                    count = count + 1

            # bucle para sacar datos, primero eliminamos todo lo que haya
            self.listbox.delete(0, self.listbox.size())
            self.listbox2.delete(0, self.listbox2.size())
            self.listbox3.delete(0, self.listbox3.size())
            self.listbox4.delete(0, self.listbox4.size())
            self.listbox5.delete(0, self.listbox5.size())
            for member in dictionary:
                self.listbox.insert(END, member)
                self.listbox2.insert(END, dictionary[member][0])
                try:
                    self.listbox3.insert(END, dictionary[member][1])
                    self.listbox4.insert(END, dictionary[member][2])
                    self.listbox5.insert(END, dictionary[member][3])
                except IndexError as error:
                    self.listbox3.insert(END, "-")
                    self.listbox5.insert(END, "-")
                    self.listbox4.insert(END, "-")

            # print(dictionary)
            # print('Longitud', len(dictionary))

            # guardamos la linea ultima leida en el diccionario
            # self.lastLine = count
            # optionsDictionary[self.name] = count
            # print('Despues:', optionsDictionary)

            # guardamos el diccionario en el archivo options
            options = open("options.txt", "w")
            for player in optionsDictionary:
                options.write(str(player) + ":" + str(optionsDictionary[player]))
            options.close()
Exemplo n.º 11
0
class OSCRemote(object):
    def __init__(self):

        self.editor_issue = "1.3"

        # get command options
        self.command_options = remote_options()

        # get directory holding the code
        self.pp_dir = sys.path[0]

        if not os.path.exists(self.pp_dir + os.sep + "pp_oscremote.py"):
            tkinter.messagebox.showwarning("Pi Presents",
                                           "Bad Application Directory")
            exit()

        # Initialise logging
        Monitor.log_path = self.pp_dir
        self.mon = Monitor()
        self.mon.init()

        Monitor.classes = ['OSCRemote', 'OSCConfig', 'OSCEditor']

        Monitor.log_level = int(self.command_options['debug'])

        self.mon.log(self, "Pi Presents Remote is starting")
        self.mon.log(self, " OS and separator " + os.name + '  ' + os.sep)
        self.mon.log(self,
                     "sys.path[0] -  location of code: code " + sys.path[0])

        self.root = Tk()

        # OSC config class
        self.osc_config = OSCConfig()
        self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg'
        self.read_create_osc()

        self.setup_gui()

        if self.osc_config.this_unit_ip == '':
            self.mon.err(self,
                         'IP of own unit must be provided in oscremote.cfg')

        self.init()

        #and start the system
        self.root.after(1000, self.run_app)
        self.root.mainloop()

    def init(self):
        #self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg'
        #self.read_create_osc()

        self.pp_home_dir = self.command_options['home'] + '/pp_home'
        self.mon.log(self, "Data Home from options is " + self.pp_home_dir)
        self.pp_profile_dir = ''

        self.current_showlist = None
        self.current_show = None
        self.current_show_ref = ''
        self.shows_display.delete(0, END)
        self.results.set('')
        self.desc.set('Listening to replies from Slave on: ' +
                      self.osc_config.this_unit_ip + ':' +
                      self.osc_config.reply_listen_port)

    def add_status(self, text):
        self.status_display.insert(END, text + '\n')
        self.status_display.see(END)

    def run_app(self):

        self.output_client = None
        self.output_reply_server = None
        self.output_reply_thread = None

        if self.osc_config.master_enabled != 'yes':
            self.mon.err(self, 'OSC Master is not enabled in oscremote.cfg')
            return

        if self.osc_config.reply_listen_port == '':
            self.mon.err(self, 'Reply Listen port is not set in oscremote.cfg')
            return

        self.prefix = '/pipresents'
        self.this_unit = '/' + self.osc_config.this_unit_name
        self.add_status("This unit's OSC address is: " + self.this_unit)
        self.slave_unit = '/' + self.osc_config.slave_units_name
        self.add_status('Slave unit OSC address is: ' + self.slave_unit)

        #connect client sending commands to slave unit then start server to listen for replies
        self.output_client = self.init_client()
        self.add_status('Listening for replies from slave on: ' +
                        self.osc_config.this_unit_ip + ':' +
                        self.osc_config.reply_listen_port)
        self.output_reply_server = self.init_server(
            self.osc_config.this_unit_ip, self.osc_config.reply_listen_port,
            self.output_client)
        self.add_output_reply_handlers()
        self.output_reply_thread = self.start_server(self.output_reply_server)

# ***************************************
#  RESPOND TO BUTTONS
# ***************************************

    def open_show(self):
        self.msg_path = '/core/open '
        self.msg_arg_text = self.current_show_ref
        self.display_msg_text()

    def close_show(self):
        self.msg_path = '/core/close '
        self.msg_arg_text = self.current_show_ref
        self.display_msg_text()

    def exit_pipresents(self):
        self.msg_path = '/core/exitpipresents'
        self.msg_arg_text = ''
        self.display_msg_text()

    def play_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-play'
        self.display_msg_text()

    def pause_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-pause'
        self.display_msg_text()
        pass

    def stop_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-stop'
        self.display_msg_text()
        pass

    def up_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-up'
        self.display_msg_text()

    def down_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-down'
        self.display_msg_text()

    def animate(self):
        self.msg_path = '/core/animate'
        self.msg_arg_text = ''
        self.display_msg_text()

    def display_control(self):
        self.msg_path = '/core/monitor'
        self.msg_arg_text = ''
        self.display_msg_text()

    def loopback(self):
        self.msg_path = '/system/loopback'
        self.msg_arg_text = ''
        self.display_msg_text()

    def server_info(self):
        self.msg_path = '/system/server-info'
        self.msg_arg_text = ''
        self.display_msg_text()

    # and put the created text in the results box in the gui
    def display_msg_text(self):
        self.results.set(self.prefix + self.slave_unit + self.msg_path + ' ' +
                         self.msg_arg_text)

    #respond to the Send button
    # parses the message string into fields and sends - NO error checking
    def send_message(self):
        if self.slave_unit == '/':
            self.mon.err(self, 'slave unit OSC name not set')
            return
        if self.osc_config.slave_units_ip == '':
            self.mon.err(self, 'slave unit IP not set')
            return
        msg_text = self.results.get()
        if msg_text == '':
            return
        fields = msg_text.split()
        osc_address = fields[0]
        arg_list = fields[1:]
        dest = (self.osc_config.slave_units_ip,
                int(self.osc_config.reply_listen_port))
        self.add_status('Send message:' + msg_text + ' to ' + str(dest))
        self.mon.log(self, 'send message: ' + msg_text)
        self.sendto(self.output_client, dest, osc_address, arg_list)

    # ***************************************
    # OSC CLIENT TO SEND MESSAGES
    # ***************************************

    def init_client(self):
        return OSC.OSCClient()

    def sendto(self, client, dest, address, arg_list):
        #print (' message to send',address,arg_list)
        msg = OSC.OSCMessage()
        msg.setAddress(address)
        for arg in arg_list:
            msg.append(arg)
        try:
            client.sendto(msg, dest)
        except Exception as e:
            self.mon.err(self,
                         'error in client when sending OSC command: ' + str(e))

    def disconnect_client(self, client):
        if client != None:
            client.close()
            return

    # ***************************************
    # OSC SERVER TO LISTEN TO REPLIES
    # ***************************************

    def init_server(self, ip, port_text, client):
        self.mon.log(self, 'Start Server: ' + ip + ':' + port_text)
        return OSC.OSCServer((ip, int(port_text)), client)

    def start_server(self, server):
        st = threading.Thread(target=server.serve_forever)
        st.start()
        return st

    def close_server(self, server, st):
        if server != None:
            server.close()
        self.mon.log(self, 'Waiting for Server-thread to finish')
        if st != None:
            st.join()  ##!!!
        self.mon.log(self, 'server thread closed')

    def add_output_reply_handlers(self):
        self.output_reply_server.addMsgHandler('default',
                                               self.no_match_handler)
        self.output_reply_server.addMsgHandler(
            self.prefix + "/system/loopback-reply",
            self.loopback_reply_handler)
        self.output_reply_server.addMsgHandler(
            self.prefix + "/system/server-info-reply",
            self.server_info_reply_handler)

    def no_match_handler(self, addr, tags, stuff, source):
        text = "No handler for message from %s" % OSC.getUrlStr(source) + '\n'
        text += "     %s" % addr + self.pretty_list(stuff, '')
        self.add_status(text + '\n')

    def loopback_reply_handler(self, addr, tags, stuff, source):
        self.add_status('Loopback reply  received from: ' +
                        OSC.getUrlStr(source))

    def server_info_reply_handler(self, addr, tags, stuff, source):
        unit = stuff[0]
        commands = stuff[1:]
        self.add_status('Server Information from: ' + OSC.getUrlStr(source))
        self.add_status('OSC name: ' + unit)
        self.add_status('Commands:\n' + self.pretty_list(commands, '\n'))

    def pretty_list(self, fields, separator):
        text = ' '
        for field in fields:
            text += str(field) + separator
        return text

    # ***************************************
    # INIT EXIT MISC
    # ***************************************

    def e_edit_osc(self):
        self.disconnect_client(self.output_client)
        self.output_client = None
        self.close_server(self.output_reply_server, self.output_reply_thread)
        self.output_reply_server = None
        self.output_reply_thread = None
        self.edit_osc()
        self.read_create_osc()
        self.init()
        self.add_status('\n\n\nRESTART')
        self.run_app()

    def app_exit(self):
        self.disconnect_client(self.output_client)
        self.close_server(self.output_reply_server, self.output_reply_thread)
        if self.root is not None:
            self.root.destroy()
        self.mon.finish()
        sys.exit()

    def show_help(self):
        tkinter.messagebox.showinfo("Help", "Read 'manual.pdf'")

    def about(self):
        tkinter.messagebox.showinfo(
            "About", "Simple Remote Control for Pi Presents\n" +
            "Author: Ken Thompson" +
            "\nWebsite: http://pipresents.wordpress.com/")

    def setup_gui(self):
        # set up the gui

        # root is the Tkinter root widget
        self.root.title("OSC Remote Control for Pi Presents")

        # self.root.configure(background='grey')

        self.root.resizable(False, False)

        # define response to main window closing
        self.root.protocol("WM_DELETE_WINDOW", self.app_exit)

        # bind some display fields
        self.desc = StringVar()
        self.filename = StringVar()
        self.display_show = StringVar()
        self.results = StringVar()
        self.status = StringVar()

        # define menu
        menubar = Menu(self.root)

        profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        profilemenu.add_command(label='Select',
                                command=self.open_existing_profile)
        menubar.add_cascade(label='Profile', menu=profilemenu)

        osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Options', menu=osc_configmenu)
        osc_configmenu.add_command(label='Edit', command=self.e_edit_osc)

        helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Help', menu=helpmenu)
        helpmenu.add_command(label='Help', command=self.show_help)
        helpmenu.add_command(label='About', command=self.about)

        self.root.config(menu=menubar)

        #top frame
        top_frame = Frame(self.root, padx=5, pady=5)
        top_frame.pack(side=TOP)

        # output info frame
        info_frame = Frame(top_frame, padx=5, pady=5)
        info_frame.pack(side=TOP, fill=BOTH, expand=1)
        info_name = Label(info_frame,
                          text="Master's Name: " +
                          self.osc_config.this_unit_name,
                          font="arial 12 bold")
        info_name.pack(side=TOP)
        info_reply_address = Label(info_frame,
                                   textvariable=self.desc,
                                   font="arial 12 bold")
        info_reply_address.pack(side=TOP)

        results_label = Label(top_frame,
                              text="Message to Send",
                              font="arial 12 bold")
        results_label.pack(side=LEFT)
        results_display = Entry(top_frame, textvariable=self.results, width=70)
        results_display.pack(side=LEFT, fill=BOTH, expand=1)
        send_button = Button(top_frame,
                             width=5,
                             height=1,
                             text='Send',
                             fg='black',
                             command=self.send_message,
                             bg="light grey")
        send_button.pack(side=RIGHT)

        #bottom frame
        bottom_frame = Frame(self.root, padx=5, pady=5)
        bottom_frame.pack(side=TOP, fill=BOTH, expand=1)
        left_frame = Frame(bottom_frame, padx=5)
        left_frame.pack(side=LEFT)
        right_frame = Frame(bottom_frame, padx=5, pady=5)
        right_frame.pack(side=LEFT)

        suplabel_frame = Frame(right_frame, pady=5)
        suplabel_frame.pack(side=TOP)
        commands_label = Label(suplabel_frame,
                               text="Show Control",
                               font="arial 12 bold")
        commands_label.pack()

        supervisor_frame = Frame(right_frame, pady=5)
        supervisor_frame.pack(side=TOP)

        # supervisor buttons
        add_button = Button(supervisor_frame,
                            width=5,
                            height=1,
                            text='Open\nShow',
                            fg='black',
                            command=self.open_show,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(supervisor_frame,
                            width=5,
                            height=1,
                            text='Close\nShow',
                            fg='black',
                            command=self.close_show,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(supervisor_frame,
                            width=10,
                            height=1,
                            text='Exit\nPi Presents',
                            fg='black',
                            command=self.exit_pipresents,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # events buttons
        oplabel_frame = Frame(right_frame, pady=5)
        oplabel_frame.pack(side=TOP)
        operations_label = Label(oplabel_frame,
                                 text="Input Events",
                                 font="arial 12 bold")
        operations_label.pack()

        operations_frame = Frame(right_frame, pady=5)
        operations_frame.pack(side=TOP)

        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Play',
                            fg='black',
                            command=self.play_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Pause',
                            fg='black',
                            command=self.pause_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Stop',
                            fg='black',
                            command=self.stop_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Up',
                            fg='black',
                            command=self.up_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Down',
                            fg='black',
                            command=self.down_event,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # animate buttons
        others_label_frame = Frame(right_frame, pady=5)
        others_label_frame.pack(side=TOP)
        others_label = Label(others_label_frame,
                             text="Others",
                             font="arial 12 bold")
        others_label.pack()

        others_frame = Frame(right_frame, pady=5)
        others_frame.pack(side=TOP)

        add_button = Button(others_frame,
                            width=5,
                            height=1,
                            text='Animate',
                            fg='black',
                            command=self.animate,
                            bg="light grey")
        add_button.pack(side=LEFT)

        add_button = Button(others_frame,
                            width=8,
                            height=1,
                            text='Monitor on/off',
                            fg='black',
                            command=self.display_control,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # system buttons
        systemlabel_frame = Frame(right_frame, pady=5)
        systemlabel_frame.pack(side=TOP)
        system_label = Label(systemlabel_frame,
                             text="System",
                             font="arial 12 bold")
        system_label.pack()

        system_frame = Frame(right_frame, pady=5)
        system_frame.pack(side=TOP)

        add_button = Button(system_frame,
                            width=5,
                            height=1,
                            text='Loopback',
                            fg='black',
                            command=self.loopback,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(system_frame,
                            width=10,
                            height=1,
                            text='Server Info',
                            fg='black',
                            command=self.server_info,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # define display of showlist
        shows_title_frame = Frame(left_frame)
        shows_title_frame.pack(side=TOP)
        shows_label = Label(shows_title_frame, text="Shows")
        shows_label.pack()
        shows_frame = Frame(left_frame)
        shows_frame.pack(side=TOP)
        scrollbar = Scrollbar(shows_frame, orient=VERTICAL)
        self.shows_display = Listbox(shows_frame,
                                     selectmode=SINGLE,
                                     height=12,
                                     width=40,
                                     bg="white",
                                     activestyle=NONE,
                                     fg="black",
                                     yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.shows_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.shows_display.pack(side=LEFT, fill=BOTH, expand=1)
        self.shows_display.bind("<ButtonRelease-1>", self.e_select_show)

        # status_frame
        status_frame = Frame(self.root, padx=5, pady=5)
        status_frame.pack(side=TOP, fill=BOTH, expand=1)
        status_label = Label(status_frame, text="Status", font="arial 12 bold")
        status_label.pack(side=LEFT)
        scrollbar = Scrollbar(status_frame, orient=VERTICAL)
        self.status_display = Text(status_frame,
                                   height=10,
                                   yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.status_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.status_display.pack(side=LEFT, fill=BOTH, expand=1)

    # ***************************************
    # SHOWLIST
    # ***************************************

    def open_existing_profile(self):
        initial_dir = self.pp_home_dir + os.sep + "pp_profiles"
        if os.path.exists(initial_dir) is False:
            self.mon.err(
                self, "Profiles directory not found: " + initial_dir +
                "\n\nHint: Data Home option must end in pp_home")
            return
        dir_path = tkinter.filedialog.askdirectory(initialdir=initial_dir)
        # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt"
        if len(dir_path) > 0:
            self.open_profile(dir_path)

    def open_profile(self, dir_path):
        showlist_file = dir_path + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(
                self, "Not a Profile: " + dir_path +
                "\n\nHint: Have you opened the profile directory?")
            return
        self.pp_profile_dir = dir_path
        self.root.title("Remote for Pi Presents - " + self.pp_profile_dir)
        self.open_showlist(self.pp_profile_dir)

    def open_showlist(self, profile_dir):
        showlist_file = profile_dir + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(
                self, "showlist file not found at " + profile_dir +
                "\n\nHint: Have you opened the profile directory?")
            self.app_exit()
        self.current_showlist = ShowList()
        self.current_showlist.open_json(showlist_file)
        # if float(self.current_showlist.sissue()) != float(self.editor_issue):
        # self.mon.err(self,"Version of profile does not match Remote: "+self.editor_issue)
        # self.app_exit()
        self.refresh_shows_display()

    def refresh_shows_display(self):
        self.shows_display.delete(0, self.shows_display.size())
        for index in range(self.current_showlist.length()):
            self.shows_display.insert(
                END,
                self.current_showlist.show(index)['title'] + "   [" +
                self.current_showlist.show(index)['show-ref'] + "]")
        if self.current_showlist.show_is_selected():
            self.shows_display.itemconfig(
                self.current_showlist.selected_show_index(), fg='red')
            self.shows_display.see(self.current_showlist.selected_show_index())

    def e_select_show(self, event):
        # print 'select show', self.current_showlist.length()
        if self.current_showlist is not None and self.current_showlist.length(
        ) > 0:
            mouse_item_index = int(event.widget.curselection()[0])
            self.current_showlist.select(mouse_item_index)
            self.current_show_ref = self.current_showlist.selected_show(
            )['show-ref']
            self.refresh_shows_display()
        else:
            self.current_show_ref = ''


# ***************************************
#  OSC CONFIGURATION
# ***************************************

    def read_create_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file, 'master')
            eosc = OSCEditor(self.root, self.osc_config_file, 'remote',
                             'Create OSC Remote Configuration')
            self.osc_config.read(self.osc_config_file)

    def edit_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
        eosc = OSCEditor(self.root, self.osc_config_file, 'remote',
                         'Edit OSC Reomote Configuration')
Exemplo n.º 12
0
class InputDevice(object):
    def __init__(self):
        # root is the Tkinter root widget
        self.root = Tk()
        self.root.title("Input Device Utility")

        # self.root.configure(background='grey')

        self.root.resizable(False, False)

        # define response to main window closing
        self.root.protocol("WM_DELETE_WINDOW", self.app_exit)

        self.my_device = ''
        self.my_device_display = StringVar()
        self.device_list = []
        self.matches = 0

        # overall display
        root_frame = Frame(self.root)
        root_frame.pack(side=LEFT)

        devices_frame = Frame(root_frame, padx=5, pady=10)
        devices_frame.pack(side=LEFT)

        devices_label = Label(devices_frame, text="Devices in dev/input")
        devices_label.pack(side=TOP)

        devices_list_frame = Frame(devices_frame, padx=5, pady=10)
        devices_list_frame.pack(side=TOP)

        selected_device_title = Label(devices_frame, text='Selected device')
        selected_device_title.pack(side=TOP)
        self.selected_device_var = StringVar()
        selected_device = Label(devices_frame,
                                textvariable=self.selected_device_var,
                                fg="red")
        selected_device.pack(side=TOP)

        events_frame = Frame(root_frame, padx=5, pady=10)
        events_frame.pack(side=LEFT)
        events_title = Label(events_frame, text='Received Events')
        events_title.pack(side=TOP)
        events_list_frame = Frame(events_frame, padx=5, pady=10)
        events_list_frame.pack(side=TOP)

        # list of devices
        scrollbar = Scrollbar(devices_list_frame, orient=VERTICAL)
        self.devices_display = Listbox(devices_list_frame,
                                       selectmode=SINGLE,
                                       height=20,
                                       width=60,
                                       bg="white",
                                       activestyle=NONE,
                                       fg="black",
                                       yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.devices_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.devices_display.pack(side=LEFT, fill=BOTH, expand=1)
        self.devices_display.bind("<ButtonRelease-1>", self.e_select_device)

        # events display
        scrollbar = Scrollbar(events_list_frame, orient=VERTICAL)
        self.events_display = Text(events_list_frame,
                                   width=40,
                                   height=20,
                                   wrap='word',
                                   font="arial 11",
                                   padx=5,
                                   yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.events_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.events_display.pack(side=LEFT, fill=BOTH, expand=1)
        self.events_display.config(state=NORMAL)
        self.events_display.delete(1.0, END)
        self.events_display.config(state=DISABLED)

        self.selected_device_index = -1
        self.matches = 0

        self.get_all_devices()
        self.refresh_devices_display()

        self.root.after(10, self.event_loop)

        # and enter Tkinter event loop
        self.root.mainloop()

    # ***************************************
    # INIT AND EXIT
    # ***************************************
    def app_exit(self):
        self.root.destroy()
        exit()

    def event_loop(self):
        if self.matches > 0:
            self.get_events()
        self.root.after(10, self.event_loop)

    def refresh_devices_display(self):
        self.devices_display.delete(0, self.devices_display.size())
        for device in self.all_devices:
            self.devices_display.insert(END, device[0] + ' ' + device[1])
        if self.selected_device_index >= 0:
            self.devices_display.itemconfig(self.selected_device_index,
                                            fg='red')
            self.devices_display.see(self.selected_device_index)

    def e_select_device(self, event):
        self.selected_device_index = -1
        if len(self.all_devices) > 0:
            self.selected_device_index = int(event.widget.curselection()[0])
            selected_device = self.all_devices[self.selected_device_index]
            self.selected_device_name = selected_device[0]
            self.selected_device_var.set(self.selected_device_name)
            self.get_matching_devices()
            self.refresh_devices_display()

    def get_all_devices(self):
        self.all_devices = []
        devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
        for device in devices:
            self.all_devices.append([device.name, device.path])

    def get_matching_devices(self):
        self.matches = 0
        self.matching_devices = []
        devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
        for device in devices:
            if self.selected_device_name in device.name:
                device_ref = evdev.InputDevice(device.path)
                self.matching_devices.append(device_ref)
                self.matches += 1

    def get_events(self):
        r, w, x = select(self.matching_devices, [], [], 0)
        if r == []:
            return
        for event in r[0].read():
            if event.type == evdev.ecodes.EV_KEY:
                key_event = evdev.categorize(event)
                if key_event.keystate == 1:
                    key_text = 'Down'
                else:
                    key_text = 'Up'
                # print key_event.keycode,key_text
                if type(key_event.keycode) is list:
                    code_text = ', '.join(key_event.keycode)
                else:
                    code_text = key_event.keycode

                self.events_display.config(state=NORMAL)
                self.events_display.insert(END,
                                           '\n' + code_text + ' ' + key_text)
                self.events_display.config(state=DISABLED)
                self.events_display.see(END)
Exemplo n.º 13
0
class TVW(Frame):
    def __init__(self, master, *args, **kwargs):
        Frame.__init__(self, master)
        ## Variables ##
        self.grid()
        self.master = master
        master.title("TVW")
        self.showList = readData(showLocation)
        if self.showList == '': self.showList = []
        self.showData = readData(showInfoLocation)
        if self.showData == '': self.showData = {}
        self.auto_updater = True
        self.run_thread = True
        self.cur_show = ''

        self.auto_progress_text = StringVar()
        self.update_progress_text = StringVar()

        self.auto_update()
        self.forceUpdate()

        ## Specialty Progress Bar ##
        # I somewhat understand this, but pulled offline to make it work
        self.style = ttk.Style(master)
        # add label in the layout
        self.style.layout('text.Horizontal.TProgressbar',
                          [('Horizontal.Progressbar.trough', {
                              'children': [('Horizontal.Progressbar.pbar', {
                                  'side': 'left',
                                  'sticky': 'ns'
                              })],
                              'sticky':
                              'nswe'
                          }), ('Horizontal.Progressbar.label', {
                              'sticky': ''
                          })])
        # set initial text
        #got arround using this to change the label of all status bars, while wanting to change each individually
        #oh well, it works
        self.style.configure('text.Horizontal.TProgressbar', text='')

        ##  Widgets  ##
        #Details
        self.details = Details(self)
        #Out Of Date Buttons, to be set per show
        self.ood_buttons = []

        self.list_frame = Frame(self)
        #list Box#
        self.list_scrollbar = Scrollbar(self.list_frame, orient="vertical")
        self.show_lb = Listbox(self.list_frame,
                               width=30,
                               height=15,
                               yscrollcommand=self.list_scrollbar.set)
        self.show_lb.bind('<<ListboxSelect>>', self.showSelect)
        self.list_scrollbar.config(command=self.show_lb.yview)
        #Add to List#
        self.add_entry = Entry(self.list_frame, text="Enter Show Name")
        self.add_button = Button(self.list_frame,
                                 text="+",
                                 command=self.newShow)
        self.delete_show = Button(self.list_frame,
                                  text="Delete This Show",
                                  command=self.deleteShow)
        #updates#
        self.update_frame = Frame(self, bg='#D0D0D0')
        self.update_align = Frame(self.update_frame, bg='#D0D0D0')
        self.update_button = Button(self.update_align,
                                    text='Refresh',
                                    command=self.forceUpdate)
        self.auto_progress = ttk.Progressbar(
            self.update_align,
            style='text.Horizontal.TProgressbar',
            variable=self.auto_progress_text,
            length=100,
            mode='determinate')
        self.update_progress = ttk.Progressbar(
            self.update_align,
            style='text.Horizontal.TProgressbar',
            variable=self.update_progress_text,
            length=100,
            mode='determinate')

        ## LAYOUT  ##
        #details#
        self.details.grid(row=0, column=1, sticky=N + E + W, padx=5, pady=5)
        #show list#
        self.list_frame.grid(row=0, column=0, rowspan=2)
        self.show_lb.grid(row=0, column=0, sticky=W)
        self.list_scrollbar.grid(row=0, column=1, sticky=N + S)
        self.add_entry.grid(row=1, column=0, sticky=E + W, pady=2)
        self.add_button.grid(row=1, column=1, sticky=W)
        self.delete_show.grid(row=2, column=0, columnspan=2, sticky=E + W)
        #update#
        self.update_frame.grid(row=1, column=1, sticky=S + E + W)
        self.update_align.pack(anchor=E)
        self.update_button.grid(row=0, column=1, sticky=E)
        self.auto_progress.grid(row=0, column=0, sticky=E)
        # have this appear only when running update
        #self.update_progress.grid(row=1,column=1, sticky=E)

    ### Aditional Functions ###
    # get show selection from Listbox
    def showSelect(self, evt):
        select = self.show_lb.curselection()
        show = self.showList[int(select[0])]
        self.cur_show = show
        self.details.updateDetails()

    # remove an out of date episode. Be up to date.
    def removeOOD(self, ep):
        print("remove", ep)
        self.showData[self.cur_show]['Out-of-Date'].remove(ep)
        self.fillListBox()
        self.details.updateDetails()
        writeData(showInfoLocation, self.showData)

    # Add new name to list of shows, update showLocation file, Run scrubbing script for new show, rerun FillListBox
    def newShow(self):
        #show_name = simpledialog.askstring("Name of new show","Please input Show Name")
        show_name = self.add_entry.get()
        if show_name != '':
            self.update([show_name])

    # progress bar in lower right.  always repeats.  When it completes, run update function
    def auto_update(self):
        def thread_auto_update():
            try:
                while self.run_thread:
                    x = 0
                    while (x <= update_timer and self.auto_updater):
                        x += progress_interval
                        time.sleep(progress_interval)
                        self.auto_progress.step(
                            100 / (update_timer / progress_interval))
                        self.style.configure(
                            'text.Horizontal.TProgressbar',
                            text='{:.0f} Seconds'.format(update_timer - x))
                    if self.run_thread != False:
                        self.update(self.showList)
                        self.auto_updater = True
                    else:
                        print('Ending Thread')
            except:
                print(
                    "Error in thread.  Likely program ended while it was running"
                )

        threading.Thread(target=thread_auto_update).start()

    # ends the current thread on auto_update, immediately forcing an update.  Will reassign and restart in auto_update
    def forceUpdate(self):
        self.auto_updater = False

    def killUpdate(self):
        self.auto_updater = False
        self.run_thread = False

    # run all steps to update data.  Scrub info from web, update list/new show times, ect
    def update(self, show_list):
        # Setup Variables
        self.add_button['state'] = 'disabled'
        self.update_button['state'] = 'disabled'
        self.update_progress.grid(row=0, column=0, sticky=W)
        progress = (100 / (1 + len(show_list)))
        self.update_progress["value"] = progress
        self.style.configure('text.Horizontal.TProgressbar', text="Updating")
        temp_show_data = {}

        #run Update on List of Shows
        for show in show_list:
            # check if program has closed
            if self.run_thread != True: break

            #Get data for Each Show, check if 404 or missing in list
            self.style.configure('text.Horizontal.TProgressbar', text=show)

            showInfo = updateData([show])

            if showInfo == "404":
                print("Server Error on '", show, "', getting 404")
            else:
                temp_show_data[show] = showInfo[show]
                if show not in self.showList:
                    self.showList.append(show)
                    writeData(showLocation, self.showList)
            self.update_progress.step(progress)

        #Writing data and updating List
        #self.style.configure('text.Horizontal.TProgressbar', text='Updating List')
        self.showData = temp_show_data
        writeData(showInfoLocation, self.showData)
        self.fillListBox()
        self.update_progress.step(progress)

        #Update is complete, user can edit things again
        self.add_button['state'] = 'normal'
        self.update_button['state'] = 'normal'
        self.update_progress.grid_forget()

    # fill in the list box elements, along with Out of Date Episode Count
    def fillListBox(self):
        ####  while updating list, check for out of date episodes, and include number for size next to name ####
        self.show_lb.delete(0, 'end')
        showCount = 1
        state = 'none'
        for show in self.showList:
            clip = ''
            clip += show
            try:
                ood = len(self.showData[show]['Out-of-Date'])
                if ood > 0:
                    clip += ' (' + str(ood) + ')'
                    state = 'ood'
            except:
                print('Error Getting Out-of-Date on ' + show)
            self.show_lb.insert(showCount, clip)
            if state != 'none':
                self.show_lb.itemconfig(showCount - 1, foreground="red")
            showCount += 1
            state = 'none'

    #delete show from all logs.  Remove from show names and from info
    def deleteShow(self):
        try:
            self.showList.remove(self.cur_show)
            del self.showData[self.cur_show]
            writeData(showLocation, self.showList)
            writeData(showInfoLocation, self.showData)
        except:
            print("No Show Specified.  Cannot delete.")

        self.fillListBox()
Exemplo n.º 14
0
class vis_tool:

    def __init__(self):
        self.args = parse_args()
        cfg = mmcv.Config.fromfile(self.args.config)
        self.window = Tk()
        self.menubar = Menu(self.window)

        self.info = StringVar()
        self.info_label = Label(
            self.window, bg='yellow', width=4, textvariable=self.info)

        self.listBox_img = Listbox(
            self.window, width=50, height=25, font=('Times New Roman', 10))
        self.listBox_obj = Listbox(
            self.window, width=50, height=12, font=('Times New Roman', 10))

        self.scrollbar_img = Scrollbar(
            self.window, width=15, orient='vertical')
        self.scrollbar_obj = Scrollbar(
            self.window, width=15, orient='vertical')

        self.listBox_img_info = StringVar()
        self.listBox_img_label = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=4,
            height=1,
            textvariable=self.listBox_img_info)

        self.listBox_obj_info = StringVar()
        self.listBox_obj_label1 = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=4,
            height=1,
            textvariable=self.listBox_obj_info)
        self.listBox_obj_label2 = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=4,
            height=1,
            text='Object Class : Score (IoU)')


        if cfg.dataset_type == 'VOCDataset':
            self.data_info = VOC_dataset(cfg, self.args)
        elif cfg.dataset_type == 'CocoDataset':
            self.data_info = COCO_dataset(cfg, self.args)

        self.info.set('DATASET: {}'.format(self.data_info.dataset))

        # load image and show it on the window
        self.img = self.data_info.get_img_by_index(0)
        self.photo = ImageTk.PhotoImage(self.img)
        self.label_img = Label(self.window, image=self.photo)

        self.show_det_txt = IntVar(value=1)
        self.checkbn_det_txt = Checkbutton(
            self.window,
            text='Text',
            font=('Arial', 10, 'bold'),
            variable=self.show_det_txt,
            command=self.change_img,
            fg='#0000FF')

        self.show_dets = IntVar(value=1)
        self.checkbn_det = Checkbutton(
            self.window,
            text='Detections',
            font=('Arial', 10, 'bold'),
            variable=self.show_dets,
            command=self.change_img,
            fg='#0000FF')

        self.show_gt_txt = IntVar(value=1)
        self.checkbn_gt_txt = Checkbutton(
            self.window,
            text='Text',
            font=('Arial', 10, 'bold'),
            variable=self.show_gt_txt,
            command=self.change_img,
            fg='#FF8C00')

        self.show_gts = IntVar(value=1)
        self.checkbn_gt = Checkbutton(
            self.window,
            text='Groundtruth',
            font=('Arial', 10, 'bold'),
            variable=self.show_gts,
            command=self.change_img,
            fg='#FF8C00')

        self.combo_label = Label(
            self.window,
            bg='yellow',
            width=10,
            height=1,
            text='Show Category',
            font=('Arial', 11))
        self.combo_category = ttk.Combobox(
            self.window,
            font=('Arial', 11),
            values=self.data_info.aug_category.combo_list)
        self.combo_category.current(0)

        self.th_label = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=10,
            height=1,
            text='Score Threshold')
        self.threshold = np.float32(0.5)
        self.th_entry = Entry(
            self.window,
            font=('Arial', 11),
            width=10,
            textvariable=StringVar(self.window, value=str(self.threshold)))
        self.th_button = Button(
            self.window, text='Enter', height=1, command=self.change_threshold)

        self.iou_th_label = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=10,
            height=1,
            text='IoU Threshold')
        self.iou_threshold = np.float32(0.5)
        self.iou_th_entry = Entry(
            self.window,
            font=('Arial', 11),
            width=10,
            textvariable=StringVar(self.window, value=str(self.iou_threshold)))
        self.iou_th_button = Button(
            self.window, text='Enter', height=1, command=self.change_iou_threshold)

        self.find_label = Label(
            self.window,
            font=('Arial', 11),
            bg='yellow',
            width=10,
            height=1,
            text='find')
        self.find_name = ''
        self.find_entry = Entry(
            self.window,
            font=('Arial', 11),
            width=10,
            textvariable=StringVar(self.window, value=str(self.find_name)))
        self.find_button = Button(
            self.window, text='Enter', height=1, command=self.findname)

        self.listBox_img_idx = 0

        # ====== ohter attribute ======
        self.img_name = ''
        self.show_img = None

        self.output = self.args.output

        if not os.path.isdir(self.output):
            os.makedirs(self.output)

        self.img_list = self.data_info.img_list

        # flag for find/threshold button switch focused element
        self.button_clicked = False

    def change_threshold(self, event=None):
        try:
            self.threshold = np.float32(self.th_entry.get())
            self.change_img()

            # after changing threshold, focus on listBox for easy control
            if self.window.focus_get() == self.listBox_obj:
                self.listBox_obj.focus()
            else:
                self.listBox_img.focus()

            self.button_clicked = True

        except ValueError:
            self.window.title('Please enter a number as score threshold.')

    def change_iou_threshold(self, event=None):

        try:
            self.iou_threshold = np.float32(self.iou_th_entry.get())
            self.change_img()

            # after changing threshold, focus on listBox for easy control
            if self.window.focus_get() == self.listBox_obj:
                self.listBox_obj.focus()
            else:
                self.listBox_img.focus()

            self.button_clicked = True

        except ValueError:
            self.window.title("Please enter a number as IoU threshold.")

    # draw groundtruth
    def draw_gt_boxes(self, img, objs):
        for obj in objs:
            cls_name = obj[0]

            # according combobox to decide whether to plot this category
            if self.combo_category.get() == 'All':
                show_category = self.data_info.aug_category.category
            else:
                show_category = [self.combo_category.get()]

            if cls_name not in show_category:
                continue

            box = obj[1:]
            xmin = max(box[0], 0)
            ymin = max(box[1], 0)
            xmax = min(box[0] + box[2], self.img_width)
            ymax = min(box[1] + box[3], self.img_height)

            font = cv2.FONT_HERSHEY_SIMPLEX

            if self.show_gt_txt.get():
                if ymax + 30 >= self.img_height:
                    cv2.rectangle(img, (xmin, ymin),
                                  (xmin + len(cls_name) * 10, int(ymin - 20)),
                                  (255, 140, 0), cv2.FILLED)
                    cv2.putText(img, cls_name, (xmin, int(ymin - 5)), font,
                                0.5, (255, 255, 255), 1)
                else:
                    cv2.rectangle(img, (xmin, ymax),
                                  (xmin + len(cls_name) * 10, int(ymax + 20)),
                                  (255, 140, 0), cv2.FILLED)
                    cv2.putText(img, cls_name, (xmin, int(ymax + 15)), font,
                                0.5, (255, 255, 255), 1)

            cv2.rectangle(img, (xmin, ymin), (xmax, ymax),
                          self.args.gt_box_color, 1)

        return img


    def get_iou(self, det):

        iou = np.zeros_like(det)
        GT = self.data_info.get_singleImg_gt(self.img_name)
        
        for idx, cls_objs in enumerate(det):

            category = self.data_info.aug_category.category[idx]
            BBGT = []
            for t in GT:
                if not t[0] == category: continue
                BBGT.append([t[1], t[2], t[1] + t[3], t[2] + t[4]])
            BBGT = np.asarray(BBGT)
            d = [0] * len(BBGT)  # for check 1 GT map to several det

            confidence = cls_objs[:, 4]
            BB = cls_objs[:, 0:4]   # bounding box        
             
            # sort by confidence
            sorted_ind = np.argsort(-confidence)
            sorted_scores = np.sort(-confidence)
            BB = BB[sorted_ind, :]

            # for returning original order
            ind_table = {i: sorted_ind[i] for i in range(len(sorted_ind))}  

            iou[idx] = np.zeros(len(BB))

            if len(BBGT) > 0:
                for i in range(len(BB)): 
                    bb = BB[i, :]
            
                    # compute overlaps
                    # intersection
                    ixmin = np.maximum(BBGT[:, 0], bb[0])
                    iymin = np.maximum(BBGT[:, 1], bb[1])
                    ixmax = np.minimum(BBGT[:, 2], bb[2])
                    iymax = np.minimum(BBGT[:, 3], bb[3])
                    iw = np.maximum(ixmax - ixmin + 1., 0.)
                    ih = np.maximum(iymax - iymin + 1., 0.)
                    inters = iw * ih
    
                    # union
                    uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) +
                           (BBGT[:, 2] - BBGT[:, 0] + 1.) * (BBGT[:, 3] - BBGT[:, 1] + 1.) - 
                            inters)

                    overlaps = inters / uni
                    ovmax = np.max(overlaps) # max overlaps with all gt
                    jmax = np.argmax(overlaps)        
                    
                    if ovmax > self.iou_threshold:        
                        if not d[jmax]:
                            d[jmax] = 1
                        else: # multiple bounding boxes map to one gt
                            ovmax = -ovmax

                    iou[idx][ind_table[i]] = ovmax # return to unsorted order
        return iou



    def draw_all_det_boxes(self, img, single_detection):

        if self.data_info.has_anno:
            self.iou = self.get_iou(single_detection)

        for idx, cls_objs in enumerate(single_detection):
            category = self.data_info.aug_category.category[idx]

            if self.combo_category.get() == 'All':
                show_category = self.data_info.aug_category.category
            else:
                show_category = [self.combo_category.get()]

            if category not in show_category:
                continue

            for obj_idx, obj in enumerate(cls_objs):
                [score, box] = [round(obj[4], 2), obj[:4]]

                if score >= self.threshold:
                    box = list(map(int, list(map(round, box))))
                    xmin = max(box[0], 0)
                    ymin = max(box[1], 0)
                    xmax = min(box[2], self.img_width)
                    ymax = min(box[3], self.img_height)

                    if not self.data_info.has_anno or \
                        self.iou[idx][obj_idx] >= self.iou_threshold:
                        color = self.args.det_box_color
                    else: 
                        color = (255, 0, 0)

                    if self.show_det_txt.get():
                        font = cv2.FONT_HERSHEY_SIMPLEX
                        text = category + ' : ' + str(score)

                        if ymax + 30 >= self.img_height:
                            cv2.rectangle(
                                img, (xmin, ymin),
                                (xmin + len(text) * 9, int(ymin - 20)),
                                (0, 0, 255), cv2.FILLED)
                            cv2.putText(img, text, (xmin, int(ymin - 5)), font,
                                        0.5, (255, 255, 255), 1)
                        else:
                            cv2.rectangle(
                                img, (xmin, ymax),
                                (xmin + len(text) * 9, int(ymax + 20)),
                                (0, 0, 255), cv2.FILLED)
                            cv2.putText(img, text, (xmin, int(ymax + 15)),
                                        font, 0.5, (255, 255, 255), 1)

                    cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color, 2)

        return img

    def draw_all_det_boxes_masks(self, img, single_detection):
        img = np.require(img, requirements=['W'])
        boxes, masks = single_detection

        # draw segmentation masks
        # reference mmdetection/mmdet/models/detectors/base.py
        if self.combo_category.get() != 'All':
            show_idx = self.data_info.aug_category.category.index(
                self.combo_category.get())
            masks = np.asarray([masks[show_idx]])
            boxes = np.asarray([boxes[show_idx]])
            category = self.data_info.aug_category.category[show_idx]

        segms = list(itertools.chain(*masks))
        bboxes = np.vstack(boxes)

        inds = np.where(np.round(bboxes[:, -1], 2) >= self.threshold)[0]

        self.color_list = []
        for i in inds:
            color_mask = np.random.randint(0, 256, (1, 3), dtype=np.uint8)
            mask = maskUtils.decode(segms[i]).astype(np.bool)
            img[mask] = img[mask] * 0.5 + color_mask * 0.5
            self.color_list.append('#%02x%02x%02x' % tuple(color_mask[0]))

        if self.data_info.has_anno:
            boxes2, _ = single_detection
            self.iou = self.get_iou(boxes2)
            if self.combo_category.get() != 'All':
                iou = np.asarray([self.iou[show_idx]])
            else:
                iou = self.iou
            
        # draw bounding box
        for idx, cls_objs in enumerate(boxes):
            if self.combo_category.get() == 'All':
                category = self.data_info.aug_category.category[idx]

            for obj_idx, obj in enumerate(cls_objs):
                [score, box] = [round(obj[4], 2), obj[:4]]

                if score >= self.threshold:
                    box = list(map(int, list(map(round, box))))
                    xmin = max(box[0], 0)
                    ymin = max(box[1], 0)
                    xmax = min(box[2], self.img_width)
                    ymax = min(box[3], self.img_height)

                    if not self.data_info.has_anno or \
                        iou[idx][obj_idx] >= self.iou_threshold:
                        color = self.args.det_box_color
                    else: 
                        color = (255, 0, 0)

                    if self.show_det_txt.get():
                        font = cv2.FONT_HERSHEY_SIMPLEX
                        text = category + ' : ' + str(score)

                        if ymax + 30 >= self.img_height:
                            cv2.rectangle(
                                img, (xmin, ymin),
                                (xmin + len(text) * 9, int(ymin - 20)),
                                (0, 0, 255), cv2.FILLED)
                            cv2.putText(img, text, (xmin, int(ymin - 5)), font,
                                        0.5, (255, 255, 255), 1)
                        else:
                            cv2.rectangle(
                                img, (xmin, ymax),
                                (xmin + len(text) * 9, int(ymax + 20)),
                                (0, 0, 255), cv2.FILLED)
                            cv2.putText(img, text, (xmin, int(ymax + 15)),
                                        font, 0.5, (255, 255, 255), 1)

                    cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color, 2)

        return img

    def change_img(self, event=None):
        if len(self.listBox_img.curselection()) != 0:
            self.listBox_img_idx = self.listBox_img.curselection()[0]

        self.listBox_img_info.set('Image  {:6}  / {:6}'.format(
            self.listBox_img_idx + 1, self.listBox_img.size()))

        name = self.listBox_img.get(self.listBox_img_idx)
        self.window.title('DATASET : ' + self.data_info.dataset + '   ' + name)

        img = self.data_info.get_img_by_name(name)
        self.img_width, self.img_height = img.width, img.height

        img = np.asarray(img)

        self.img_name = name
        self.img = img

        if self.data_info.has_anno and self.show_gts.get():
            objs = self.data_info.get_singleImg_gt(name)
            img = self.draw_gt_boxes(img, objs)

        if self.data_info.results is not None and self.show_dets.get():
            if self.data_info.mask is False:
                dets = self.data_info.get_singleImg_dets(name)
                img = self.draw_all_det_boxes(img, dets)
            else:
                dets = self.data_info.get_singleImg_dets(name).transpose(
                    (1, 0))
                img = self.draw_all_det_boxes_masks(img, dets)

            self.clear_add_listBox_obj()

        self.show_img = img
        img = Image.fromarray(img)
        img = self.scale_img(img)
        self.photo = ImageTk.PhotoImage(img)
        self.label_img.config(image=self.photo)
        self.window.update_idletasks()

        if self.img_name in os.listdir(self.output):
            self.listBox_img_label.config(bg='#CCFF99')
        else:
            self.listBox_img_label.config(bg='yellow')

    def draw_one_det_boxes(self, img, single_detection, selected_idx=-1):
        idx_counter = 0
        for idx, cls_objs in enumerate(single_detection):

            category = self.data_info.aug_category.category[idx]
            if self.combo_category.get() == 'All':
                show_category = self.data_info.aug_category.category
            else:
                show_category = [self.combo_category.get()]

            if category not in show_category:
                continue

            for obj_idx, obj in enumerate(cls_objs):
                [score, box] = [round(obj[4], 2), obj[:4]]

                if score >= self.threshold:
                    if idx_counter == selected_idx:
                        box = list(map(int, list(map(round, box))))
                        xmin = max(box[0], 0)
                        ymin = max(box[1], 0)
                        xmax = min(box[2], self.img_width)
                        ymax = min(box[3], self.img_height)

                        if not self.data_info.has_anno or \
                            self.iou[idx][obj_idx] >= self.iou_threshold:
                            color = self.args.det_box_color
                        else: 
                            color = (255, 0, 0)

                        if self.show_det_txt.get():
                            font = cv2.FONT_HERSHEY_SIMPLEX
                            text = category + ' : ' + str(score)

                            if ymax + 30 >= self.img_height:
                                cv2.rectangle(
                                    img, (xmin, ymin),
                                    (xmin + len(text) * 9, int(ymin - 20)),
                                    (0, 0, 255), cv2.FILLED)
                                cv2.putText(img, text, (xmin, int(ymin - 5)),
                                            font, 0.5, (255, 255, 255), 1)
                            else:
                                cv2.rectangle(
                                    img, (xmin, ymax),
                                    (xmin + len(text) * 9, int(ymax + 20)),
                                    (0, 0, 255), cv2.FILLED)
                                cv2.putText(img, text, (xmin, int(ymax + 15)),
                                            font, 0.5, (255, 255, 255), 1)

                        cv2.rectangle(img, (xmin, ymin), (xmax, ymax), color, 2)

                        return img
                    else:
                        idx_counter += 1

    def draw_one_det_boxes_masks(self, img, single_detection, selected_idx=-1):
        img = np.require(img, requirements=['W'])
        boxes, masks = single_detection

        # draw segmentation masks
        # reference mmdetection/mmdet/models/detectors/base.py
        if self.combo_category.get() != 'All':
            show_idx = self.data_info.aug_category.category.index(
                self.combo_category.get())
            category = self.data_info.aug_category.category[
                show_idx]  # fixed category
            masks = np.asarray([masks[show_idx]])
            boxes = np.asarray([boxes[show_idx]])

        segms = list(itertools.chain(*masks))
        bboxes = np.vstack(boxes)

        inds = np.where(np.round(bboxes[:, -1], 2) >= self.threshold)[0]

        self.color_list = []
        for inds_idx, i in enumerate(inds):
            if inds_idx == selected_idx:
                color_mask = np.random.randint(0, 256, (1, 3), dtype=np.uint8)
                mask = maskUtils.decode(segms[i]).astype(np.bool)
                img[mask] = img[mask] * 0.5 + color_mask * 0.5
                self.color_list.append('#%02x%02x%02x' % tuple(color_mask[0]))

        if self.data_info.has_anno:
            if self.combo_category.get() != 'All':
                iou = np.asarray([self.iou[show_idx]])
            else:
                iou = self.iou
                
        # draw bounding box
        idx_counter = 0
        for idx, cls_objs in enumerate(boxes):
            if self.combo_category.get() == 'All':
                category = self.data_info.aug_category.category[idx]

            for obj_idx, obj in enumerate(cls_objs):
                [score, box] = [round(obj[4], 2), obj[:4]]

                if score >= self.threshold:
                    if idx_counter == selected_idx:
                        box = list(map(int, list(map(round, box))))
                        xmin = max(box[0], 0)
                        ymin = max(box[1], 0)
                        xmax = min(box[2], self.img_width)
                        ymax = min(box[3], self.img_height)

                        if not self.data_info.has_anno or \
                            iou[idx][obj_idx] >= self.iou_threshold:
                            color = self.args.det_box_color
                        else: 
                            color = (255, 0, 0)

                        if self.show_det_txt.get():
                            font = cv2.FONT_HERSHEY_SIMPLEX
                            text = category + ' : ' + str(score)

                            if ymax + 30 >= self.img_height:
                                cv2.rectangle(
                                    img, (xmin, ymin),
                                    (xmin + len(text) * 9, int(ymin - 20)),
                                    (0, 0, 255), cv2.FILLED)
                                cv2.putText(img, text, (xmin, int(ymin - 5)),
                                            font, 0.5, (255, 255, 255), 1)
                            else:
                                cv2.rectangle(
                                    img, (xmin, ymax),
                                    (xmin + len(text) * 9, int(ymax + 20)),
                                    (0, 0, 255), cv2.FILLED)
                                cv2.putText(img, text, (xmin, int(ymax + 15)),
                                            font, 0.5, (255, 255, 255), 1)

                        cv2.rectangle(img, (xmin, ymin), (xmax, ymax),
                                      color, 2)

                        return img
                    else:
                        idx_counter += 1

    # plot only one object
    def change_obj(self, event=None):
        if len(self.listBox_obj.curselection()) == 0:
            self.listBox_img.focus()
            return
        else:
            listBox_obj_idx = self.listBox_obj.curselection()[0]

        self.listBox_obj_info.set('Detected Object : {:4}  / {:4}'.format(
            listBox_obj_idx + 1, self.listBox_obj.size()))

        name = self.listBox_img.get(self.listBox_img_idx)
        img = self.data_info.get_img_by_name(name)
        self.img_width, self.img_height = img.width, img.height
        img = np.asarray(img)
        self.img_name = name
        self.img = img

        if self.data_info.has_anno and self.show_gts.get():
            objs = self.data_info.get_singleImg_gt(name)
            img = self.draw_gt_boxes(img, objs)

        if self.data_info.results is not None and self.show_dets.get():

            if self.data_info.mask is False:
                dets = self.data_info.get_singleImg_dets(name)
                img = self.draw_one_det_boxes(img, dets, listBox_obj_idx)
            else:
                dets = self.data_info.get_singleImg_dets(name).transpose(
                    (1, 0))
                img = self.draw_one_det_boxes_masks(img, dets, listBox_obj_idx)

        self.show_img = img
        img = Image.fromarray(img)
        img = self.scale_img(img)
        self.photo = ImageTk.PhotoImage(img)
        self.label_img.config(image=self.photo)
        self.window.update_idletasks()

        if self.img_name in os.listdir(self.output):
            self.listBox_img_label.config(bg='#CCFF99')
        else:
            self.listBox_img_label.config(bg='yellow')

    # ============================================

    def scale_img(self, img):
        [s_w, s_h] = [1, 1]

        # if window size is (1920, 1080),
        # the default max image size is (1440, 810)
        (fix_width, fix_height) = (1440, 810)

        # change image size according to window size
        if self.window.winfo_width() != 1:
            fix_width = (
                self.window.winfo_width() - self.listBox_img.winfo_width() -
                self.scrollbar_img.winfo_width() - 5)
            # fix_height = int(fix_width * 9 / 16)
            fix_height = 750

        # handle image size is too big
        if img.width > fix_width:
            s_w = fix_width / img.width
        if img.height > fix_height:
            s_h = fix_height / img.height

        scale = min(s_w, s_h)
        img = img.resize((int(img.width * scale), int(img.height * scale)),
                         Image.ANTIALIAS)
        return img

    def clear_add_listBox_obj(self):
        self.listBox_obj.delete(0, 'end')

        if self.data_info.mask is False:
            single_detection = self.data_info.get_singleImg_dets(
                self.img_list[self.listBox_img_idx])
        else:
            single_detection, single_mask = self.data_info.get_singleImg_dets(
                self.img_list[self.listBox_img_idx]).transpose((1, 0))

        if self.combo_category.get() == 'All':
            show_category = self.data_info.aug_category.category
        else:
            show_category = [self.combo_category.get()]

        num = 0
        for idx, cls_objs in enumerate(single_detection):
            category = self.data_info.aug_category.category[idx]

            if category not in show_category:
                continue

            for obj_idx, obj in enumerate(cls_objs):
                score = np.round(obj[4], 2)
                if score >= self.threshold:
                    if not self.data_info.has_anno:
                        self.listBox_obj.insert('end', 
                                                category + " : " + str(score))
                    elif self.iou[idx][obj_idx] > self.iou_threshold:
                        s = "{:15} : {:5.3} ( {:<6.3})".format(
                            category, score, abs(round(self.iou[idx][obj_idx], 2)))
                        self.listBox_obj.insert('end', s)
                        self.listBox_obj.itemconfig(num, fg="green")
                    else:
                        s = "{:15} : {:5.3} ( {:<6.3})".format(
                            category, score, abs(round(self.iou[idx][obj_idx], 2)))
                        self.listBox_obj.insert('end', s)
                        self.listBox_obj.itemconfig(num, fg="red")

                    num += 1

        self.listBox_obj_info.set('Detected Object : {:3}'.format(num))

    def change_threshold_button(self, v):
        self.threshold += v

        if self.threshold <= 0:
            self.threshold = 0
        elif self.threshold >= 1:
            self.threshold = 1

        self.th_entry.delete(0, END)
        self.th_entry.insert(0, str(round(self.threshold, 2)))
        self.change_threshold()

    def change_iou_threshold_button(self, v):
        self.iou_threshold += v

        if self.iou_threshold <= 0:
            self.iou_threshold = 0
        elif self.iou_threshold >= 1:
            self.iou_threshold = 1

        self.iou_th_entry.delete(0, END)
        self.iou_th_entry.insert(0, str(round(self.iou_threshold, 2)))
        self.change_iou_threshold()


    def save_img(self):
        print('Save image to ' + os.path.join(self.output, self.img_name))
        cv2.imwrite(
            os.path.join(self.output, self.img_name),
            cv2.cvtColor(self.show_img, cv2.COLOR_BGR2RGB))
        self.listBox_img_label.config(bg='#CCFF99')

    def eventhandler(self, event):
        entry_list = [self.find_entry, self.th_entry, self.iou_th_entry]
        if self.window.focus_get() not in entry_list:
            if platform.system() == 'Windows':
                state_1key = 8
                state_2key = 12
            else:  # 'Linux'
                state_1key = 16
                state_2key = 20
          
            if event.state == state_2key and event.keysym == 'Left':
                self.change_iou_threshold_button(-0.1)
            elif event.state == state_2key and event.keysym == 'Right':
                self.change_iou_threshold_button(0.1) 

            elif event.state == state_1key and event.keysym == 'Left':
                self.change_threshold_button(-0.1)
            elif event.state == state_1key and event.keysym == 'Right':
                self.change_threshold_button(0.1)
            elif event.keysym == 'q':
                self.window.quit()
            elif event.keysym == 's':
                self.save_img()

            if self.button_clicked:
                self.button_clicked = False
            else:
                if event.keysym in ['KP_Enter', 'Return']:
                    self.listBox_obj.focus()
                    self.listBox_obj.select_set(0)
                elif event.keysym == 'Escape':
                    self.change_img()
                    self.listBox_img.focus()

    def combobox_change(self, event=None):
        self.listBox_img.focus()
        self.change_img()

    def clear_add_listBox_img(self):
        self.listBox_img.delete(0, 'end')  # delete listBox_img 0 ~ end items

        # add image name to listBox_img
        for item in self.img_list:
            self.listBox_img.insert('end', item)

        self.listBox_img.select_set(0)
        self.listBox_img.focus()
        self.change_img()

    def findname(self, event=None):
        self.find_name = self.find_entry.get()
        new_list = []

        if self.find_name == '':
            new_list = self.data_info.img_list
        else:
            for img_name in self.data_info.img_list:
                if self.find_name[0] == '!':
                    if self.find_name[1:] not in img_name:
                        new_list.append(img_name)
                else:
                    if self.find_name in img_name:
                        new_list.append(img_name)

        if len(new_list) != 0:
            self.img_list = new_list
            self.clear_add_listBox_img()
            self.clear_add_listBox_obj()
            self.button_clicked = True
        else:
            self.window.title("Can't find any image about '{}'".format(
                self.find_name))

    def run(self):
        self.window.title('DATASET : ' + self.data_info.dataset)
        self.window.geometry('1280x800+350+100')

        # self.menubar.add_command(label='QUIT', command=self.window.quit)
        self.window.config(menu=self.menubar)  # display the menu
        self.scrollbar_img.config(command=self.listBox_img.yview)
        self.listBox_img.config(yscrollcommand=self.scrollbar_img.set)
        self.scrollbar_obj.config(command=self.listBox_obj.yview)
        self.listBox_obj.config(yscrollcommand=self.scrollbar_obj.set)

        layer1 = 0
        layer2 = 50

        # ======================= layer 1 =========================

        # combobox
        self.combo_label.grid(
            row=layer1 + 30,
            column=0,
            sticky=W + E + N + S,
            padx=3,
            pady=3,
            columnspan=6)
        self.combo_category.grid(
            row=layer1 + 30,
            column=6,
            sticky=W + E + N + S,
            padx=3,
            pady=3,
            columnspan=6)

        # show det
        self.checkbn_det.grid(
            row=layer1 + 40,
            column=0,
            sticky=N + S,
            padx=3,
            pady=3,
            columnspan=4)
        # show det text
        self.checkbn_det_txt.grid(
            row=layer1 + 40,
            column=4,
            sticky=N + S,
            padx=3,
            pady=3,
            columnspan=2)
        if self.data_info.has_anno != False:
            # show gt
            self.checkbn_gt.grid(
                row=layer1 + 40,
                column=6,
                sticky=N + S,
                padx=3,
                pady=3,
                columnspan=4)
            # show gt text
            self.checkbn_gt_txt.grid(
                row=layer1 + 40,
                column=10,
                sticky=N + S,
                padx=3,
                pady=3,
                columnspan=2)

        # ======================= layer 2 =========================

        self.listBox_img_label.grid(
            row=layer2 + 0, column=0, sticky=N + S + E + W, columnspan=12)

        # find name
        self.find_label.grid(
            row=layer2 + 20, column=0, sticky=E + W, columnspan=4)
        self.find_entry.grid(
            row=layer2 + 20, column=4, sticky=E + W, columnspan=4)
        self.find_button.grid(
            row=layer2 + 20, column=8, sticky=E + W, pady=3, columnspan=4)

        self.scrollbar_img.grid(row=layer2 + 30, column=11, sticky=N + S + W)
        self.label_img.grid(
            row=layer1 + 30,
            column=12,
            sticky=N + E,
            padx=3,
            pady=3,
            rowspan=110)
        self.listBox_img.grid(
            row=layer2 + 30,
            column=0,
            sticky=N + S + E + W,
            pady=3,
            columnspan=11)

        if self.data_info.det_file != '':
            self.th_label.grid(
                row=layer2 + 40, column=0, sticky=E + W, columnspan=6)
            self.th_entry.grid(
                row=layer2 + 40, column=6, sticky=E + W, columnspan=3)
            self.th_button.grid(
                row=layer2 + 40, column=9, sticky=E + W, columnspan=3)

            if self.data_info.has_anno != False:
                self.iou_th_label.grid(
                    row=layer2 + 50, column=0, sticky=E + W, columnspan=6)
                self.iou_th_entry.grid(
                    row=layer2 + 50, column=6, sticky=E + W, columnspan=3)
                self.iou_th_button.grid(
                    row=layer2 + 50, column=9, sticky=E + W, columnspan=3)

            self.listBox_obj_label1.grid(
                row=layer2 + 60, column=0, sticky=E + W, pady=3, columnspan=12)

            if self.data_info.has_anno != False:
                self.listBox_obj_label2.grid(
                    row=layer2 + 70, 
                    column=0, 
                    sticky=E + W, 
                    pady=2, 
                    columnspan=12)

            self.scrollbar_obj.grid(
                row=layer2 + 80, column=11, sticky=N + S + W, pady=3)
            self.listBox_obj.grid(
                row=layer2 + 80,
                column=0,
                sticky=N + S + E + W,
                pady=3,
                columnspan=11)

        self.clear_add_listBox_img()
        self.listBox_img.bind('<<ListboxSelect>>', self.change_img)
        self.listBox_img.bind_all('<KeyRelease>', self.eventhandler)

        self.listBox_obj.bind('<<ListboxSelect>>', self.change_obj)

        self.th_entry.bind('<Return>', self.change_threshold)
        self.th_entry.bind('<KP_Enter>', self.change_threshold)
        self.iou_th_entry.bind('<Return>', self.change_iou_threshold)
        self.iou_th_entry.bind('<KP_Enter>', self.change_iou_threshold)
        self.find_entry.bind('<Return>', self.findname)
        self.find_entry.bind('<KP_Enter>', self.findname)

        self.combo_category.bind('<<ComboboxSelected>>', self.combobox_change)

        self.window.mainloop()
Exemplo n.º 15
0
class convertTab:
    def __init__(self, root):
        self.root = root
        self.conversioning = False
        self._upperFrame()
        self._lowerFrame()

    def _upperFrame(self):
        frame = LabelFrame(self.root, text="Paths")
        frame.grid(row=0,
                   column=0,
                   sticky="snew",
                   padx=(5, 5),
                   pady=(5, 5),
                   ipady=10,
                   ipadx=10)
        frame.columnconfigure(1, weight=5)
        frame.columnconfigure(2, weight=1)
        self.targetLabel = Label(frame,
                                 text="Save to",
                                 fg="blue",
                                 cursor="hand2")
        self.targetLabel.grid(row=0,
                              column=0,
                              sticky="w",
                              padx=(10, 10),
                              pady=(15, 6))
        self.targetLabel.bind("<Button-1>", lambda event: self._dirBrowse())
        f = font.Font(self.targetLabel, self.targetLabel.cget("font"))
        f.configure(underline=True)
        self.targetLabel.configure(font=f)
        self.pathLabel = Label(frame, text=DDIR, fg="grey", anchor="w")
        self.pathLabel.grid(row=0,
                            column=1,
                            sticky="we",
                            padx=(10, 10),
                            pady=(15, 6),
                            columnspan=2)

        Label(frame, text="Files").grid(row=1,
                                        column=0,
                                        sticky="wn",
                                        padx=(10, 10),
                                        pady=(15, 6))

        def addListBox():
            textFrame = Frame(frame)
            textFrame.grid(row=1,
                           column=1,
                           sticky="ew",
                           padx=(10, 10),
                           pady=(15, 6),
                           rowspan=3)
            textFrame.columnconfigure(0, weight=1)
            self.lst = Listbox(textFrame, selectmode=MULTIPLE)
            self.lst.grid(row=0, column=0, sticky="snew")
            scrllx = Scrollbar(textFrame,
                               orient="horizontal",
                               command=self.lst.xview)
            scrlly = Scrollbar(textFrame,
                               orient="vertical",
                               command=self.lst.yview)
            self.lst["xscrollcommand"] = scrllx.set
            self.lst["yscrollcommand"] = scrlly.set
            scrllx.grid(row=1, column=0, sticky="snew")
            scrlly.grid(row=0, column=1, sticky="snew")

        addListBox()
        self.addBtn = Button(frame,
                             text="add",
                             relief="groove",
                             command=self._addToListBox)
        self.removeBtn = Button(frame,
                                text="remove",
                                relief="groove",
                                command=self._removeFromList)
        self.clearBtn = Button(frame,
                               text="clear",
                               relief="groove",
                               command=self._clearList)
        self.addBtn.grid(row=1,
                         column=2,
                         sticky="ews",
                         padx=(5, 10),
                         pady=(15, 6))
        self.removeBtn.grid(row=2,
                            column=2,
                            sticky="ew",
                            padx=(5, 10),
                            pady=(15, 6))
        self.clearBtn.grid(row=3,
                           column=2,
                           sticky="ewn",
                           padx=(5, 10),
                           pady=(15, 6))

    def _fileBrowse(self):
        get = askopenfile()
        if get != None:
            if not path.splitext(path.basename(get.name))[1][1:] in [
                    "mp3", "mp4", "3gp", "wav", "m4a", "flac", "wma", "acc",
                    "ogg", "mp2", "amr", "webm", "gif"
            ]:
                messagebox.showerror("media error",
                                     "the type of the file is not allowed")
            else:
                self.lst.insert(0, get.name)

    def _dirBrowse(self):
        get = askdirectory()
        if get != "": self.pathLabel.config(text=get)

    def _clearList(self):
        for i in range(self.lst.size()):
            self.lst.delete(i, END)

    def _removeFromList(self):
        items = self.lst.curselection()
        pos = 0
        for i in items:
            idx = int(i) - pos
            self.lst.delete(idx, idx)
            pos = pos + 1
        self._colorListBox()

    def _addToListBox(self):
        self._fileBrowse()
        self._colorListBox()

    def _colorListBox(self):
        for i in range(self.lst.size()):
            if i % 2 == 1:
                self.lst.itemconfig(i, {"bg": "#e8dada"})
            else:
                self.lst.itemconfig(i, {"bg": "#FFF"})

    #mp3 wav m4a flac wma acc ogg mp2 amr
    def _lowerFrame(self):
        frame = LabelFrame(self.root, text="Conversion")
        frame.grid(row=1,
                   column=0,
                   sticky="snew",
                   padx=(5, 5),
                   pady=(5, 5),
                   ipady=10,
                   ipadx=10)
        #frame.columnconfigure(0,weight=1)
        frame.columnconfigure(1, weight=1)
        frame.rowconfigure(2, weight=1)
        text = "You can change the type of media files, by giving their path at the previous step,\nthen choose the new format of them, we have design it to be very easy for novice users it's just one click to go"
        lbl = Label(frame, text=text, justify="center")
        lbl.grid(row=0,
                 column=0,
                 sticky="we",
                 padx=(10, 10),
                 pady=(15, 20),
                 columnspan=2)
        Label(frame, text="choose profile ").grid(row=1,
                                                  column=0,
                                                  padx=(10, 10),
                                                  sticky="w")

        def addOptionMenu(row, col):
            self.format = StringVar(frame)
            options = [
                "mp3", "mp4", "wav", "m4a", "flac", "wma", "acc", "3gp", "ogg",
                "mp2", "amr", "webm", "gif"
            ]
            self.format.set(options[0])
            optionMenu = Combobox(frame,
                                  textvariable=self.format,
                                  state="readonly",
                                  values=options)
            optionMenu.grid(row=row,
                            column=col,
                            sticky="we",
                            ipady=1,
                            padx=(10, 10))

        addOptionMenu(1, 1)
        self.convertBtn = Button(
            frame,
            text="Convert",
            relief="groove",
            command=lambda: self._startNewThread(self._conversion, ()))
        self.convertBtn.grid(row=2,
                             column=1,
                             sticky="se",
                             columnspan=2,
                             padx=(10, 10),
                             pady=(10, 5),
                             ipady=2,
                             ipadx=3)
        self.convertInfo = Label(frame, text="")
        self.convertInfo.grid(row=2,
                              column=0,
                              sticky="sw",
                              padx=(10, 10),
                              pady=(10, 5),
                              ipady=2,
                              ipadx=3)

    def _startNewThread(self, func, args):
        thrd = Thread(target=func, args=args)
        thrd.setDaemon(True)
        thrd.start()

    def _conversion(self):
        total = self.lst.size()
        self.convertBtn.configure(state="disabled")
        if total == 0: return
        success = 0
        failed = 0
        files = []
        f = self.format.get()
        for index in range(total):
            files.append(self.lst.get(index))

        for index in range(len(files)):
            self.convertInfo.configure(text="please wait " + str((index + 1)) +
                                       " of " + str(total) + " ...")
            result = changeFormat(files[index], self.pathLabel.cget("text"), f)
            if result == False: failed += 1
            elif result == True: success += 1

        self.convertInfo.configure(text="total: " + str(total) + " success: " +
                                   str(success) + " failed: " + str(failed))
        self.convertBtn.configure(state="active")
Exemplo n.º 16
0
class ProjectListForm:
    def __init__(self, Cache, conn):
        self.Cache = Cache
        self.Connection = conn

        master = Tk()
        self.Master = master
        master.protocol('WM_DELETE_WINDOW', self.Quit)
        self.Master.title("Projects")

        self.AddButton = Button(master, text='Add', command=self.Add)
        self.AddButton.grid(row=0, column=0, sticky='NSEW')

        self.EditButton = Button(master, text='Edit', command=self.Edit)
        self.EditButton.grid(row=0, column=1, sticky='NSEW')

        self.DeleteButton = Button(master, text='Delete', command=self.Delete)
        self.DeleteButton.grid(row=0, column=2, sticky='NSEW')

        self.ActivationButton = Button(master,
                                       text='(De)Activate',
                                       command=self.ToggleActivation)
        self.ActivationButton.grid(row=0, column=3, sticky='NSEW')

        self.ShowOnlyActive = False
        self.ShowActiveOnlyButton = Button(master,
                                           text='Show Only Active',
                                           command=self.ToggleActiveProjects)
        self.ShowActiveOnlyButton.grid(row=0, column=4, sticky='NSEW')

        self.ProjectsListBox = Listbox(master, width=80)
        self.ProjectsListBox.grid(row=1,
                                  column=0,
                                  columnspan=10,
                                  sticky='NSEW')

        self.FillProjects()

        self.ProjectsListBox.bind('<Double-1>', lambda x: self.Edit())

    # def CloseWindow(self):
    #     self.Master.quit()

    def Quit(self):
        self.Master.quit()

    def Show(self):
        self.Master.mainloop()

    def ToggleActivation(self):
        sel = self.ProjectsListBox.curselection()[0]
        project = self.Cache.AllProjects[sel]
        if project.Active == 0:
            project.Active = 1
        else:
            project.Active = 0
            project.Button = None
        bl = BLProject.BLProject(self.Connection)
        bl.Update(project)
        self.Cache.RefreshProjects()
        self.FillProjects()

    def ToggleActiveProjects(self):
        self.ShowOnlyActive = not self.ShowOnlyActive
        self.FillProjects()

    def FillProjects(self):
        self.ProjectsListBox.delete(0, END)
        if self.ShowOnlyActive:
            projects = self.Cache.ActiveProjects
        else:
            projects = self.Cache.AllProjects
        for item in projects:
            self.ProjectsListBox.insert(END, item)
        for i in range(0, self.ProjectsListBox.size()):
            item = projects[i]
            active = item.Active
            if active == 0:
                self.ProjectsListBox.itemconfig(i, {'bg': 'red'})

    def Add(self):
        pr = ProjectEditForm(self.Connection)
        pr.Show()
        self.Cache.RefreshProjects()
        self.FillProjects()
        pr.Master.destroy()

    def Edit(self):
        sel = self.ProjectsListBox.curselection()[0]
        project = self.GetProject(sel)
        pr = ProjectEditForm(self.Connection, project)
        pr.Show()
        self.Cache.RefreshProjects()
        self.FillProjects()
        pr.Master.destroy()

    def Delete(self):
        sel = self.ProjectsListBox.curselection()[0]
        project = self.GetProject(sel)
        bl = BLProject.BLProject(self.Connection)
        bl.DeleteByID(project.ID)
        self.Cache.RefreshProjects()
        self.FillProjects()

    def GetProject(self, ID):
        if self.ShowOnlyActive:
            return self.Cache.ActiveProjects[ID]
        else:
            return self.Cache.AllProjects[ID]
Exemplo n.º 17
0
class StatePopup(object):
    def __init__(self, master, default_value, state_probs):
        top = self.top = Toplevel(master.canvas)
        self.master = master

        self.l = Label(top, text="New State")
        self.l.grid(row=0, column=0, columnspan=2)

        self.lb = Listbox(
            top
        )  # OptionMenu(top, Tkinter.StringVar().set(self.states[-1]), *self.states)
        self.lb.insert("end", "0")
        for i, (state,
                color) in enumerate(self.master.trail.colorlist.items()):
            str = ",".join(["{:x}".format(x) for x in state])
            self.lb.insert("end", str)
            self.lb.itemconfig(i + 1, {"bg": color})
        self.lb.grid(row=1, column=1, padx=(MARGIN_LR // 2), pady=MARGIN_TB)
        self.lb.config(height=5, width=8)
        self.lb.bind(
            "<Double-Button-1>",
            lambda x: self.set_text(self.lb.get(self.lb.curselection())))

        self.e = Entry(top)
        self.e.insert(0, default_value)
        self.e.bind("<Control-KeyRelease-a>", lambda x: self.select_all())
        self.e.grid(row=1,
                    column=0,
                    sticky=N,
                    padx=(MARGIN_LR // 2),
                    pady=MARGIN_TB)
        self.e.select_range(0, 'end')
        self.e.icursor('end')
        self.e.focus()

        self.b = Button(top, text='Ok', command=self.check_cleanup)
        self.top.protocol("WM_DELETE_WINDOW", self.close)
        self.b.grid(row=3, column=0, columnspan=2)

        self.l2 = Label(top, text="Probabilities")
        self.l2.grid(row=4, column=0, columnspan=2)
        for i, x in enumerate(state_probs):
            # if x > 0:
            #    l = Label(top, text=hex(i)[2:] + ":" + str(x))
            #    l.pack()
            pass

        self.top.bind("<Return>", lambda x: self.check_cleanup())
        self.top.bind("<Escape>", lambda x: self.close())
        self.value = None
        self.top.wait_visibility()
        # stop interaction in other gui
        self.top.grab_set()

    def set_text(self, text):
        self.e.delete(0, 'end')
        self.e.insert(0, text)

    def select_all(event):
        event.e.select_range(0, 'end')
        # move cursor to the end
        event.e.icursor('end')
        return 'break'

    def check_cleanup(self):
        newstate = self.e.get()
        if newstate == "":
            self.value = list(
                range(
                    0, 2**(self.master.trail.statebitsize //
                           self.master.trail.statesize)))
        elif newstate == "*":
            self.value = list(
                range(
                    1, 2**(self.master.trail.statebitsize //
                           self.master.trail.statesize)))
        else:
            try:
                state = []
                for x in newstate.split(","):
                    x = x.strip()
                    x = int(x, 16)
                    assert x < 2**(self.master.trail.statebitsize //
                                   self.master.trail.statesize)
                    state.append(x)
                assert len(state) > 0
                self.value = state
            except Exception as e:
                print("Exception: " + str(e))
                self.value = None
                return

        self.close()

    def close(self):
        self.top.grab_release()
        self.top.destroy()
Exemplo n.º 18
0
    def CurrentSongInfo(self):
        def OnPlayListClick(event):
            newsongtitle = PlayList.get(PlayList.curselection())
            for i in range(0, int(length)):
                try:
                    if (songlist[i]['title'] == newsongtitle):
                        newsongindex = i
                        break
                except KeyError:
                    if (songlist[i]['artist'] == newsongtitle):
                        newsongindex = i
                        break

            rpi.playid(songlist[newsongindex]['id'])
            rpi.update()

        def ftime(time):
            time = int(time)
            return str(int(time / 60)) + ':' + '%.2d' % int(time % 60)

        self.currentsong = StringVar(self)
        rpi.update()
        cs = rpi.currentsong()
        ss = rpi.status()
        try:
            artist = cs['artist']
        except KeyError:
            artist = '**'
        try:
            album = cs['album']
        except KeyError:
            album = '**'
        try:
            title = cs['title']
        except KeyError:
            title = '**'
        #track = cs['track']
        try:
            num = str(int(ss['song']) + 1)
        except KeyError:
            num = ''
        length = ss['playlistlength']
        try:
            cur_time = ftime(ss['time'].split(':')[0])
        except KeyError:
            cur_time = "0:00"
        # total time
        try:
            total_time = ftime(cs['time'])
        except KeyError:
            total_time = "0:00"
        self.currentsong.set(artist + ' - ' + title + '\n' + album + '\n' +
                             num + '/' + length + '\n\n' + cur_time + '/' +
                             total_time)
        lblframe = LabelFrame(self, text="Now Playing", width=600, height=100)
        lblframe.grid(row=1, column=0, columnspan=7, pady=40)
        #lblframe.grid(row=0, column=1)
        lblframe.grid_propagate(0)
        lbl = Label(lblframe,
                    textvariable=self.currentsong,
                    font=('Tahoma', (9)))
        lbl.grid(row=1, column=0)
        lbl.grid_propagate(0)

        PlayList = Listbox(self, width=80)
        PlayList.grid(row=3, column=1, columnspan=5, padx=20)

        songlist = rpi.playlistid()
        for i in range(0, int(length)):
            try:
                PlayList.insert(i, songlist[i]['title'])
            except KeyError:
                PlayList.insert(i, songlist[i]['artist'])
            if (len(cs) != 0):
                if (cs['id'] == songlist[i]['id']):
                    PlayList.itemconfig(i,
                                        background='blue',
                                        foreground='white')

        PlayList.bind('<<ListboxSelect>>', OnPlayListClick)
Exemplo n.º 19
0
class ListFrame(Frame):
    def __init__(self, master,
                 root, recursive,
                 regex, repl,
                 options):
        Frame.__init__(self, master)

        self._left_list = Listbox(self)
        self._left_list.pack(side=LEFT, fill=BOTH, expand=True)
        
        self._right_list = Listbox(self)
        self._right_list.pack(side=LEFT, fill=BOTH, expand=True)
        self._right_scroll = Scrollbar(self._right_list, orient=VERTICAL)
        self._right_list.config(yscrollcommand=self._right_scroll.set)
        self._right_scroll.config(command=self._right_list.yview)

        self._scrollbar = Scrollbar(self, orient=VERTICAL, command=self._scroll_scrollbar)
        self._scrollbar.pack(side=RIGHT, fill=Y)
        self._left_list.config(yscrollcommand=self._scroll_left)
        self._right_list.config(yscrollcommand=self._scroll_right)

        self._regex = regex
        self._repl = repl
        self._settings = options
        self._root = None
        self._recursive = None
        self._names = None
        self._mapping = None
        self._errors = None
        self._update_root(root, recursive)

        master.bind('<<RootUpdate>>', self._on_root_update)
        master.bind('<<RegexUpdate>>', self._on_regex_update)
        master.bind('<<OptionsUpdate>>', self._on_options_update)
        master.bind('<<Refresh>>', self._on_refresh)

    def _scroll_left(self, sfrom, sto):
        self._scrollbar.set(sfrom, sto)
        self._right_list.yview('moveto', sfrom)

    def _scroll_right(self, sfrom, sto):
        self._scrollbar.set(sfrom, sto)
        self._left_list.yview('moveto', sfrom)

    def _scroll_scrollbar(self, *args):
        self._left_list.yview(*args)
        self._right_list.yview(*args)

    def _on_root_update(self, event):
        self._update_root(event.widget.root, event.widget.recursive)

    def _on_regex_update(self, event):
        self._update_regex(event.widget.regex, event.widget.repl)

    def _on_refresh(self, event):
        self._update_root(self._root, self._recursive)

    def _on_options_update(self, event):
        self._settings = event.widget.options
        self._update_lists()

    def _update_regex(self, regex, repl):
        self._regex = regex
        self._repl = repl
        self._update_lists()

    def _is_type_enabled(self, ftype):
        if ftype is True:
            return self._settings.files
        elif ftype is False:
            return self._settings.dirs
        else:
            return self._settings.others

    def _walk(self):
        for root, dirs, files in os.walk(self._root):
            for name in files + dirs:
                path = os.path.join(root, name)
                yield os.path.relpath(path, self._root)

    def _entries(self):
        if self._recursive:
            return self._walk()
        else:
            return os.listdir(self._root)

    def _update_root(self, root, recursive):
        self._root = root
        self._recursive = recursive
        self._left_list.delete(0, END)
        self._names = []
        if self._root:
            for name in sorted(self._entries()):
                path = os.path.join(self._root, name)
                ftype = None
                if os.path.isfile(path):
                    ftype = True
                if os.path.isdir(path):
                    ftype = False
                self._names.append((name, ftype))

        self._update_lists()

    def _insert_name_both(self, name, color, color_right_only=False):
        idx = self._left_list.size()
        self._left_list.insert(END, name)
        if not color_right_only:
            self._left_list.itemconfig(idx, dict(fg=color))
        self._right_list.insert(END, name)
        self._right_list.itemconfig(idx, dict(fg=color))

    def _update_lists(self):
        self._mapping = []
        self._errors = []
        rev_mapping = {}
        self._left_list.delete(0, END)
        self._right_list.delete(0, END)

        if not self._repl:
            self._errors.append('Invalid replacement string')
        
        for name, ftype in self._names:
            enabled = self._is_type_enabled(ftype)
            if enabled or not self._settings.hide_wrong_type:
                if not enabled or not self._regex:
                    self._insert_name_both(name, 'gray')
                elif self._regex and not self._regex.match(name):
                    if not self._settings.hide_mismatches:
                        self._insert_name_both(name, 'gray')
                elif not self._repl:
                    self._insert_name_both(name, 'gray', color_right_only=True)
                else:
                    idx = self._left_list.size()
                    right_name = self._regex.sub(self._repl, name)
                    self._left_list.insert(END, name)
                    self._right_list.insert(END, right_name)

                    if name != right_name:
                        self._mapping.append((name, right_name))

                        right_path = os.path.join(self._root, right_name)
                        if os.path.exists(right_path):
                            error = 'File already exists: %s' % right_name
                        elif right_name in rev_mapping:
                            other_name, other_idx = rev_mapping[right_name]
                            colliding_sources = name, other_name
                            error = 'Name collision: %s <- %s | %s' % (right_name, *colliding_sources)
                            self._right_list.itemconfig(other_idx, dict(fg='red'))
                        else:
                            error = None
                            rev_mapping[right_name] = name, idx

                        if error:
                            self._errors.append(error)
                            self._right_list.itemconfig(idx, dict(fg='red'))

    @property
    def mapping(self):
        if not self._errors:
            return self._mapping

    @property
    def errors(self):
        return self._errors
Exemplo n.º 20
0
class MyFirstGUI:
    def __init__(self, tkRoot):
        self.tkRoot = tkRoot

        self.con = pyodbc.connect(driver="{SQL Server}",
                                  server=".",
                                  database="DomoticaDB")
        self.dbCmd = "SELECT * FROM [dbo].[Items]"

        tkRoot.title("SQL monitor")
        # Top Frame --- --- ---
        self.labelsFrame = Frame(tkRoot)
        self.labelsFrame.pack(fill="both", expand='YES')

        self.listbox = Listbox(self.labelsFrame)
        self.listbox.pack(fill="both", expand='YES')
        self.listbox.config(font='Consolas', justify='center')

        # Bottom Frame --- --- ---
        self.bottomFrame = Frame(tkRoot)
        self.bottomFrame.pack(fill="both", expand='YES')

        self.label = Label(self.bottomFrame, text="Placeholder")
        self.label.pack(side="left", expand='yes')

        self.entry = Entry(self.bottomFrame, width=0)
        self.entry.insert(0, self.dbCmd)
        self.entry.pack(side="left", expand='yes')

        # Root Frame --- --- ---
        self.greet_button = Button(tkRoot,
                                   text="Update Query",
                                   command=self.update_query)
        self.greet_button.pack()

        self.close_button = Button(tkRoot, text="Close", command=tkRoot.quit)
        self.close_button.pack()

        self.tkRoot.after(1000, self.update)

    def update_query(self):
        self.label.configure(text=self.entry.get())
        self.dbCmd = self.entry.get()

    def update(self):
        msg = self.get_sql(self.dbCmd)
        self.listbox.delete(0, END)
        [self.listbox.insert(END, item) for item in msg]

        for each in range(0, self.listbox.size()):
            self.listbox.itemconfig(each, bg=self.tkRoot['bg'])

        self.listbox.config(width=0)
        self.tkRoot.after(1000, self.update)

        #self.entry.delete(0, "end")
        #self.entry.insert(0, self.dbCmd)

    def get_sql(self, cmd):
        cur = self.con.cursor()
        res = cur.execute(cmd)

        ret = []
        for r in res:
            for each in [0, 3, 4]:
                if (r[each] is None):
                    r[each] = ""
            ret.append(
                f"Id: {r[0]:>10} \tName: {r[3][:20] : <25} \tNice name: {r[4][:20]:<25}"
            )  #" \tknown_device_id: {r[10]}")

            # if( "zwave" in r[4]):
            #     if(r[3] is not None and r[9] is not None):
            #         ret.append()
            #     else:
            #         if r[3] is None:
            #             r[3] = "None"
            #         if r[9] is None:
            #             r[9] = "None"
            #         ret.append(f"Id: {r[0]} \tName: {r[3][:20]:<25} \tNice name: {r[9][:20]:<25} \tknown_device_id: {r[11]}")
        return ret
Exemplo n.º 21
0
class Gui(Tk):
    biome_listbox = None
    biome_listbox_lbl = None
    biome_filter_var = None
    biome_filter_box = None

    biome_select_btn = None

    study_listbox = None
    study_listbox_lbl = None
    study_select_btn = None
    study_filter_var = None
    study_filter_box = None

    study_id_disp = None
    study_id_var = None

    study_title_disp = None
    study_title_var = None

    study_desc_disp = None
    study_desc_var = None

    study_scientific_names = None
    study_sci_names_var = None

    biome_selection_btn = None
    biome_selection = None
    biome_selection_lbl = None
    biome_tag_btn = None

    tagging_confirmation_lbl = None
    tagging_confirmation_var = None

    suggested_biomes = []

    ena_view_btn = None

    def __init__(self, biome_classifier=None):
        # Create the menu
        super().__init__()
        args = parse_args()
        self.btc = BiomeTaggingTool(args.db)
        self.biome_classifier = biome_classifier

        self.list_frame = Frame()
        self.list_frame.grid(row=1, column=0, padx=10, pady=3)
        self.details_frame = Frame()
        self.details_frame.grid(row=3, column=0, padx=10, pady=3)
        header = Label(self, text='Tagging biomes on db: ' + args.db)
        header.grid(row=0, column=0, padx=10, pady=3)

        self.title = 'Biome tagging!'

        self.biomes_list = get_biomes()

        self.init_biome_list()
        self.init_study_list()

        self.init_study_display()
        self.init_biome_conf_display()
        self.init_confirmation_line()

    def init_biome_list(self):
        self.biome_listbox_lbl = Label(self.list_frame,
                                       text='List of biomes (click to select)')
        self.biome_listbox_lbl.grid(row=0, column=1, padx=10, pady=3)
        self.biome_listbox = Listbox(self.list_frame, width=75)
        self.biome_listbox.grid(row=1, column=1, padx=10, pady=3)

        self.biome_listbox.bind('<Double-Button>', self.select_biome)
        for b in self.biomes_list:
            self.biome_listbox.insert(END, b)
        self.biome_filter_var = StringVar()
        self.biome_filter_var.trace(
            "w", lambda name, index, mode: self.filter_biome_list())

        biome_filter_row = Frame(self.list_frame)
        biome_filter_row.grid(row=2, column=1, padx=10, pady=3)
        biome_filter_lbl = Label(biome_filter_row, text='Search biomes: ')
        biome_filter_lbl.grid(row=0, column=0, padx=10, pady=3)

        self.biome_match_case = IntVar()
        self.biome_filter_caps_checkbox = Checkbutton(
            biome_filter_row,
            text='Match case',
            variable=self.biome_match_case,
            command=self.filter_biome_list)
        self.biome_filter_caps_checkbox.grid(row=1, column=0, padx=10, pady=3)

        self.biome_filter_box = Entry(biome_filter_row,
                                      textvariable=self.biome_filter_var,
                                      width=50)
        self.biome_select_btn = Button(biome_filter_row,
                                       text='Select biome',
                                       command=self.select_biome)
        self.biome_filter_box.grid(row=0, column=1, padx=10, pady=3)
        self.biome_select_btn.grid(row=0, column=2, padx=10, pady=3)

        self.filter_biome_list()

    def filter_study_list(self):
        search_term = self.study_filter_var.get()
        self.study_listbox.delete(0, END)
        list_studies = []

        # Append non-suggested biomes which pass filter
        for s in self.btc.studies:
            accessions = (s.primary_accession + ' ' +
                          s.secondary_accession).lower()
            if search_term.lower() in accessions:
                list_studies.append(s.secondary_accession)

        # Insert into listbox and color items if needed
        for i, s in enumerate(list_studies):
            self.study_listbox.insert(END, s)

    def filter_biome_list(self):
        search_term = self.biome_filter_var.get()
        self.biome_listbox.delete(0, END)
        list_biomes = []

        index_colors = {}

        # Insert suggested biomes at top of list IF they match the filter text, and store indeces to colour them later
        for b in self.suggested_biomes:
            s = '{} ({} match)'.format(b[0], "{0:.2f}".format(b[1]))
            is_match = search_term.lower() in b[0].lower(
            ) if not self.biome_match_case.get() else search_term in b[0]
            if is_match:
                i = len(list_biomes)
                list_biomes.append(s)
                b_color = fmt_font_intensity(b[1])
                index_colors[i] = _from_rgb((255 - b_color, 0, b_color))

        # Append non-suggested biomes which pass filter
        for b in self.biomes_list:
            is_match = search_term.lower() in b.lower(
            ) if not self.biome_match_case.get() else search_term in b
            if is_match and b not in self.suggested_biomes:
                list_biomes.append(b)

        # Insert into listbox and color items if needed
        for i, b in enumerate(list_biomes):
            self.biome_listbox.insert(END, b)
            if i in index_colors:
                self.biome_listbox.itemconfig(i, {'fg': index_colors[i]})

    def init_study_list(self):
        self.study_listbox = Listbox(self.list_frame, width=75)
        self.update_study_list()
        self.study_listbox_lbl = Label(
            self.list_frame, text='List of studies that need tagging')
        self.study_listbox_lbl.grid(row=0, column=0, padx=10, pady=3)
        self.study_listbox.grid(row=1, column=0, padx=10, pady=3)

        study_filter_row = Frame(self.list_frame)
        study_filter_row.grid(row=2, column=0, padx=10, pady=3)
        study_filter_lbl = Label(study_filter_row,
                                 text='Search Study accession: ')
        study_filter_lbl.grid(row=0, column=0, padx=10, pady=3)

        self.study_filter_var = StringVar()
        self.study_filter_var.trace(
            "w", lambda name, index, mode: self.filter_study_list())

        self.study_filter_box = Entry(study_filter_row,
                                      textvariable=self.study_filter_var,
                                      width=50)
        self.study_filter_box.grid(row=0, column=1, padx=10, pady=3)

        self.study_select_btn = Button(study_filter_row,
                                       text='Select study',
                                       command=self.select_study)
        self.study_listbox.bind('<Double-Button>', self.select_study)
        self.study_select_btn.grid(row=0, column=3, padx=10, pady=3)

        self.ena_view_btn = Button(self.list_frame,
                                   text='View study in ENA',
                                   command=self.view_in_ena)
        self.ena_view_btn.grid(row=3, column=0, padx=10, pady=3)

    def view_in_ena(self):
        webbrowser.open_new("https://www.ebi.ac.uk/ena/data/view/" +
                            self.study_id_var.get().replace('Study id: ', ''))

    def init_study_display(self):
        self.study_id_var = StringVar(self)
        self.study_title_var = StringVar(self)
        self.study_desc_var = StringVar(self)
        self.study_sci_names_var = StringVar(self)

        self.study_id_disp = Label(self.details_frame,
                                   textvariable=self.study_id_var,
                                   wraplength=750)
        self.study_id_disp.grid(row=0, column=0, padx=10, pady=3)
        self.study_title_disp = Label(self.details_frame,
                                      textvariable=self.study_title_var,
                                      wraplength=750)
        self.study_title_disp.grid(row=1, column=0, padx=10, pady=3)

        self.study_desc_frame = Frame(self.details_frame)
        self.study_desc_frame.grid(row=2, column=0)

        self.study_desc_disp = tkscrolled.ScrolledText(self.study_desc_frame,
                                                       height=20,
                                                       width=140,
                                                       wrap='word')
        self.study_desc_disp.insert(0.0, '\n' + self.study_desc_var.get())
        self.study_desc_disp['font'] = ('consolas', '14')
        self.study_desc_disp.pack(expand=True, fill='both')

        self.study_scientific_names = Label(
            self.details_frame,
            textvariable=self.study_sci_names_var,
            wraplength=750)
        self.study_scientific_names.grid(row=3, column=0, padx=10, pady=3)

    def fetch_study(self, study_id):
        if study_id not in study_cache:
            study = self.btc.studies.filter(secondary_accession=study_id)[0]
            d = self.btc.fetch_info(study)
            study_cache[study_id] = d
        else:
            d = study_cache[study_id]
        print('Fetched ' + study_id)
        return d

    def select_study(self, *args, **kwargs):
        try:
            print('selecting')
            study_id = self.study_listbox.get(
                self.study_listbox.curselection())
            d = self.fetch_study(study_id)
            self.study_id_var.set('Study id: {}'.format(study_id))
            self.study_title_var.set('Title: {}'.format(d['title']))
            text = 'Abstract: {}'.format(d['abstract'])
            self.study_desc_disp.delete(1.0, END)
            self.study_desc_disp.insert(1.0, '\n' + text)
            self.study_desc_disp.see(0.0)

            # self.study_sci_names_var.set('Environment variable names: {}'.format(", ".join(d['scientific_names'])))
            self.reset_confirmation_line()
            self.suggested_biomes = self.biome_classifier.pred_input(
                (d['title'] or '') + ' ' + (d['abstract'] or ''))
            self.filter_biome_list()
        except TclError as e:
            logging.error(e)
            pass

    def reset_study_display(self):
        self.study_id_var.set('Study id:')
        self.study_title_var.set('Title:')
        self.study_desc_var.set('Description:')
        self.study_sci_names_var.set('Environment variable names:')

    def init_biome_conf_display(self):
        self.biome_selection = StringVar(value='Selected biome: ')
        self.biome_selection_lbl = Label(self.details_frame,
                                         textvariable=self.biome_selection)
        self.biome_selection_lbl.grid(row=0, column=1, padx=10, pady=3)
        self.biome_tag_btn = Button(self.details_frame,
                                    text='Tag biome',
                                    command=self.tag_biome_handler)
        self.biome_tag_btn.grid(row=1, column=1, padx=10, pady=3)

    def select_biome(self, *args, **kwargs):
        try:
            biome = self.biome_listbox.get(self.biome_listbox.curselection())
            self.biome_selection.set('Selected biome: {}'.format(biome))
            logging.info('Selected biome: ' + biome)
        except TclError:
            print('err')
            pass

    def tag_biome_handler(self, *args, **kwargs):
        study_id = self.study_id_var.get().replace('Study id: ', '')
        biome = self.biome_selection.get().replace('Selected biome: ', '')
        logging.info('Tagging {} with biome {}'.format(study_id, biome))
        lineage = re.sub('(\(\d\.\d+ match\))', '', biome)
        self.btc.tag_study(study_id, lineage)

        self.remove_study_from_list(study_id)
        self.reset_study_display()
        self.set_confirmation_line(study_id, biome)

        self.suggested_biomes = []
        self.filter_biome_list()

    def remove_study_from_list(self, study_id):
        logging.info('Removing study {} from list.'.format(study_id))
        self.btc.update_taggable_studies()
        self.update_study_list()

    def update_study_list(self):
        for i, s in enumerate(
                sorted([s.secondary_accession for s in self.btc.studies])):
            if self.study_listbox.get(i) != s:
                self.study_listbox.insert(i, s)
        self.study_listbox.delete(len(self.btc.studies), END)

    def init_confirmation_line(self):
        self.tagging_confirmation_var = StringVar(value='')
        self.tagging_confirmation_lbl = Label(
            self, textvariable=self.tagging_confirmation_var, fg="red")
        self.tagging_confirmation_lbl.grid(row=4, column=0, padx=10, pady=3)

    def set_confirmation_line(self, study_id, biome):
        s = 'Study {} was tagged with biome {}'.format(study_id, biome)
        self.tagging_confirmation_var.set(s)

    def reset_confirmation_line(self):
        self.tagging_confirmation_var.set('')
Exemplo n.º 22
0
class MainScreen:
    def __init__(self, master, connection):
        #Reset Database if necessary
        Globals.ClearUserTables(connection)
        self.Config = configparser.ConfigParser()
        self.Config.read('config.ini')

        #Main Window
        self.Master = master
        self.Master.title("Hour Registration")

        #Database connection
        self.dbConnection = connection

        #Initialize Cache
        self.Cache = Cache.Cache(connection)

        #Initialize String Vars
        self.RecordTypeValue = StringVar()
        self.ProjectValue = StringVar()
        self.DescriptionValue = StringVar()
        self.LastLogon = StringVar()
        self.LastLogon.set(Globals.GetLastLogon())

        #Designer
        self.DaysCombo = ttk.Combobox(master)
        self.DaysCombo.grid(row=0, column=0, sticky='NSEW', columnspan=3)

        self.RecordButton = Button(master,
                                   text="Start Recording",
                                   command=self.StartRecording)
        self.RecordButton.grid(row=1, column=0, sticky='NSEW')
        self.RecordIcon = PhotoImage(file=".\\Resources\\add.png")
        self.RecordButton.config(image=self.RecordIcon,
                                 width="32",
                                 height="32")

        self.DeleteRecordButton = Button(master,
                                         text="Delete Record",
                                         command=self.DeleteRecord)
        self.DeleteRecordButton.grid(row=1, column=1, sticky='NSEW')
        self.DeleteRecordIcon = PhotoImage(file=".\\Resources\\delete.png")
        self.DeleteRecordButton.config(image=self.DeleteRecordIcon,
                                       width="32",
                                       height="32")

        self.StopRecordButton = Button(master,
                                       text="Stop Recording",
                                       command=self.StopRecording)
        self.StopRecordButton.grid(row=1, column=2, sticky='NSEW')
        self.StopRecordIcon = PhotoImage(file=".\\Resources\\stop.png")
        self.StopRecordButton.config(image=self.StopRecordIcon,
                                     width="32",
                                     height="32")

        self.CopyToCodexButton = Button(master,
                                        text="Copy To Codex",
                                        command=self.CopyToCodex)
        self.CopyToCodexButton.grid(row=2, column=0, sticky='NSEW')
        self.CopyIcon = PhotoImage(file=".\\Resources\\copyCodex.png")
        self.CopyToCodexButton.config(image=self.CopyIcon,
                                      width="32",
                                      height="32")

        self.ExcelButton = Button(master,
                                  text="Export",
                                  command=self.ExportToExcel)
        self.ExcelButton.grid(row=2, column=1, sticky='NSEW')
        self.ExcelIcon = PhotoImage(file=".\\Resources\\excel.png")
        self.ExcelButton.config(image=self.ExcelIcon, width="32", height="32")

        self.ProjectButton = Button(master,
                                    text="Project",
                                    command=self.OpenProjectListForm)
        self.ProjectButton.grid(row=2, column=2, sticky='NSEW')
        self.ProjectIcon = PhotoImage(file=".\\Resources\\add_project.png")
        self.ProjectButton.config(image=self.ProjectIcon,
                                  width="32",
                                  height="32")

        self.CopyRecordButton = Button(master,
                                       text="CopyRecord",
                                       command=self.CopyRecord)
        self.CopyRecordButton.grid(row=3, column=0, sticky='NSEW')
        self.CopyRecordIcon = PhotoImage(file=".\\Resources\\copy.png")
        self.CopyRecordButton.config(image=self.CopyRecordIcon,
                                     width="32",
                                     height="32")

        self.OneNoteButton = Button(master,
                                    text="OneNote",
                                    command=self.OpenInOneNote)
        self.OneNoteButton.grid(row=3, column=1, sticky='NSEW')
        self.OneNoteIcon = PhotoImage(file=".\\Resources\\onenote.png")
        self.OneNoteButton.config(image=self.OneNoteIcon,
                                  width="32",
                                  height="32")

        self.AddTimeRecordButton = Button(master,
                                          text="AddTimeRecordButton",
                                          command=self.ShowNewEditForm)
        self.AddTimeRecordButton.grid(row=3, column=2, sticky="NSEW")
        self.AddTimeRecordIcon = PhotoImage(
            file=".\\Resources\\application_add.png")
        self.AddTimeRecordButton.config(image=self.AddTimeRecordIcon,
                                        width="32",
                                        height="32")

        self.BackupButton = Button(master,
                                   text="BackupButton",
                                   command=self.DatabaseBackup)
        self.BackupButton.grid(row=4, column=0, sticky="NSEW")
        self.BackupButtonIcon = PhotoImage(file=".\\Resources\\angel.png")
        self.BackupButton.config(image=self.BackupButtonIcon,
                                 width="32",
                                 height="32")

        self.RecordTypeButton = Button(master,
                                       text="RecordType",
                                       command=self.OpenRecordTypeListForm)
        self.RecordTypeButton.grid(row=4, column=1, sticky="NSEW")
        self.RecordTypeButtonIcon = PhotoImage(
            file=".\\Resources\\recordType.png")
        self.RecordTypeButton.config(image=self.RecordTypeButtonIcon,
                                     width="32",
                                     height="32")

        self.ExportToGraphsButton = Button(master,
                                           text="ExportToGraphs",
                                           command=self.ExportToGraph)
        self.ExportToGraphsButton.grid(row=4, column=2, sticky="NSEW")
        self.ExportToGraphsButtonIcon = PhotoImage(
            file=".\\Resources\\chart.png")
        self.ExportToGraphsButton.config(image=self.ExportToGraphsButtonIcon,
                                         width="32",
                                         height="32")

        self.ProjectsCombo = ttk.Combobox(master,
                                          textvariable=self.ProjectValue)
        self.ProjectsCombo.grid(row=0, column=3, columnspan=2, sticky='NSEW')

        self.RecordTypeCombo = ttk.Combobox(master,
                                            textvariable=self.RecordTypeValue)
        self.RecordTypeCombo.grid(row=1, column=3, columnspan=2, sticky='NSEW')

        self.DescriptionTextBox = Entry(master,
                                        textvariable=self.DescriptionValue)
        self.DescriptionTextBox.grid(row=2,
                                     column=3,
                                     columnspan=2,
                                     sticky='NSEW')

        self.RecordsListBox = Listbox(master, width=50)
        self.RecordsListBox.grid(row=3,
                                 column=3,
                                 rowspan=7,
                                 columnspan=1,
                                 sticky='NSEW')

        self.CommentListBox = Listbox(master, width=70)
        self.CommentListBox.grid(row=3,
                                 column=4,
                                 rowspan=7,
                                 columnspan=2,
                                 sticky='NSEW')
        self.CommentListBox.bindtags((self.CommentListBox, master, "all"))

        self.EventLogExplanationLabel = Label(master,
                                              text="Laatst aangemeld op: ")
        self.EventLogExplanationLabel.grid(row=0, column=5)

        self.EventLogLabel = Label(master, textvariable=self.LastLogon)
        self.EventLogLabel.grid(row=1, column=5)

        self.DaysCombo.bind("<<ComboboxSelected>>",
                            self.DaysCombo_SelectedItemChanged)
        self.RecordsListBox.bind("<<ListboxSelect>>",
                                 self.RecordsListBox_SelectedItemChanged)
        self.RecordsListBox.bind('<Double-1>', lambda x: self.ShowEditForm())
        #End Designer

        #Set Form Controls
        self.FillCombos()
        self.SetButtonsEnabled()

        self.Queue = queue.Queue(10)
        self.KillEvent = threading.Event()
        self.ControllerThread = threading.Thread(target=self.ctrl,
                                                 args=(self.Queue,
                                                       self.KillEvent))
        self.ControllerThread.start()
        Logger.LogInfo(self.ControllerThread.getName() + ' started.')

        self.CheckForUpdatesFromController()

    def ctrl(self, queue, killEvent):
        dac = DAController.DAController(queue, killEvent)
        dac.Listen()

    def DatabaseBackup(self):
        source = self.Config['DEFAULT']['databasename']
        destination = self.Config['DEFAULT'][
            'databasebackuplocation'] + '{}.db'.format(
                time.strftime('%Y%m%d%H%M'))
        copyfile(source, destination)
        messagebox.showinfo('Backup', 'Database backup made')

    def CheckForUpdatesFromController(self):
        if not self.Queue.empty():
            queue = self.Queue.get()
            blPr = BLProject.BLProject(self.dbConnection)
            project = blPr.GetByButton(queue)
            if project is not None:
                print(project.Description)
                recordType = 1
                blTr = BLTimeRecord.BLTimeRecord(self.dbConnection)
                for record in self.Cache.TimeRecords:
                    if record.StatusID == TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value:
                        record.StatusID = TimeRecordStatusEnum.TimeRecordStatusEnum.Gestopt.value
                        record.EndHour = Globals.GetCurrentTime()
                        blTr.Update(record)
                timeRecord = TimeRecord.TimeRecord(
                    None, Globals.GetCurrentTime(), None, project.ID,
                    recordType, 'Automatically generated',
                    TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value, 0,
                    None, None)
                valid = TimeRecordValidation.TimeRecordValidation()
                validationMessage = valid.ValidateOnCreation(timeRecord)
                if not len(validationMessage) == 0:
                    errorMessage = ''
                    for i in validationMessage:
                        errorMessage = errorMessage + i + '\n'
                    messagebox.showerror('Error', errorMessage)
                else:
                    index = self.DaysCombo.current()
                    blTr.Create(timeRecord)
                    self.Cache.RefreshAllStaticData()
                    self.FillCombos()
                    if index == -1: index = 0
                    self.DaysCombo.current(index)
                    self.RefreshTimeRecords()
        self.Master.after(500, self.CheckForUpdatesFromController)

    def OpenInOneNote(self):
        sel = self.RecordsListBox.curselection()[0]
        timeRecordView = self.Cache.TimeRecordViews[sel]
        os.system("start " + timeRecordView.OneNoteLink)

    def CopyRecord(self):
        blTr = BLTimeRecord.BLTimeRecord(self.dbConnection)
        sel = self.RecordsListBox.curselection()[0]
        timeRecordView = self.Cache.TimeRecordViews[sel]
        timeRecord = blTr.GetById(timeRecordView.ID)
        blTr.CopyTimeRecord(timeRecord)
        self.Refresh()

    def Refresh(self):
        index = self.DaysCombo.current()
        self.DaysCombo.current(0)
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        self.DaysCombo.current(index)
        self.RefreshTimeRecords()
        self.SetButtonsEnabled()

    def RecordsListBox_SelectedItemChanged(self, eventObject):
        self.SetButtonsEnabled()

    def DaysCombo_SelectedItemChanged(self, eventObject):
        self.RefreshTimeRecords()
        self.SetButtonsEnabled()

    def RefreshTimeRecords(self):
        index = self.DaysCombo.current()
        if not index == -1:
            date = self.Cache.DayViews[index].Date
            self.Cache.RefreshTimeRecordsForDate(date)
            self.FillTimeRecords(self.Cache.TimeRecordViews)
        else:
            self.RecordsListBox.delete(0, END)
            self.CommentListBox.delete(0, END)

    def Show(self):
        self.Master.mainloop()

    def FillCombos(self):
        self.FillProjectCombo()
        self.FillRecordTypeCombo()
        self.FillDays()

    def FillProjectCombo(self):
        self.ProjectsCombo['value'] = self.Cache.ActiveProjects

    def FillRecordTypeCombo(self):
        self.RecordTypeCombo['value'] = self.Cache.RecordTypes

    def FillDays(self):
        self.DaysCombo['value'] = self.Cache.DayViews

    def FillTimeRecords(self, timeRecordViews):
        self.RecordsListBox.delete(0, END)
        self.CommentListBox.delete(0, END)
        for item in timeRecordViews:
            self.RecordsListBox.insert(END, item)
            self.CommentListBox.insert(END, item.Description)
        for i in range(0, self.RecordsListBox.size()):
            item = timeRecordViews[i]
            itemStatus = item.Status
            if itemStatus == 'Gestart':
                self.RecordsListBox.itemconfig(i, {'bg': 'red'})
            elif itemStatus == 'Gestopt':
                self.RecordsListBox.itemconfig(i, {'bg': 'green'})
            elif itemStatus == 'Gekopieerd':
                self.RecordsListBox.itemconfig(i, {'bg': 'orange'})

    def StartRecording(self):
        recordIndex = self.RecordTypeCombo.current()
        projectIndex = self.ProjectsCombo.current()
        if recordIndex == -1: recordType = ''
        else: recordType = self.Cache.RecordTypes[recordIndex].ID
        if projectIndex == -1: project = None
        else: project = self.Cache.ActiveProjects[projectIndex].ID
        timeRecord = TimeRecord.TimeRecord(
            None, Globals.GetCurrentTime(), None, project, recordType,
            self.DescriptionValue.get(),
            TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value, 0, None,
            None)

        valid = TimeRecordValidation.TimeRecordValidation()
        validationMessage = valid.ValidateOnCreation(timeRecord)
        if not len(validationMessage) == 0:
            errorMessage = ''
            for i in validationMessage:
                errorMessage = errorMessage + i + '\n'
            messagebox.showerror('Error', errorMessage)
        else:
            index = self.DaysCombo.current()
            blTr = BLTimeRecord.BLTimeRecord(self.dbConnection)
            blTr.Create(timeRecord)
            self.Cache.RefreshAllStaticData()
            self.FillCombos()
            if index == -1: index = 0
            self.DaysCombo.current(index)
            self.RefreshTimeRecords()

    def StopRecording(self):
        blTr = BLTimeRecord.BLTimeRecord(self.dbConnection)
        sel = self.RecordsListBox.curselection()[0]
        timeRecordView = self.Cache.TimeRecordViews[sel]
        timeRecord = blTr.GetById(timeRecordView.ID)
        timeRecord.EndHour = Globals.GetCurrentTime()

        timeRecord.StatusID = TimeRecordStatusEnum.TimeRecordStatusEnum.Gestopt.value
        blTr.Update(timeRecord)
        index = self.DaysCombo.current()
        self.DaysCombo.current(0)
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        self.DaysCombo.current(index)
        self.RefreshTimeRecords()
        self.SetButtonsEnabled()

    def CopyToCodex(self):
        self.Master.clipboard_clear()
        index = self.DaysCombo.current()
        date = self.Cache.DayViews[index].Date
        self.Master.clipboard_append(
            Globals.CopyToCodex(self.dbConnection, date))
        self.RefreshTimeRecords()

    def ShowEditForm(self):
        timeRecordView = self.Cache.TimeRecordViews[
            self.RecordsListBox.curselection()[0]]
        edit = TimeRecordEditForm(self.dbConnection, timeRecordView,
                                  self.Cache)
        edit.Show()
        index = self.DaysCombo.current()
        self.DaysCombo.current(0)
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        self.DaysCombo.current(index)
        self.RefreshTimeRecords()
        edit.Master.destroy()

    def ShowNewEditForm(self):
        tr = TimeRecordView.TimeRecordView(None, None, None, None, None, None,
                                           None, None, None, None, None)
        index = self.DaysCombo.current()
        tr.Date = self.Cache.DayViews[index].Date
        edit = TimeRecordEditForm(self.dbConnection, tr, self.Cache)
        edit.Show()
        index = self.DaysCombo.current()
        self.DaysCombo.current(0)
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        self.DaysCombo.current(index)
        self.RefreshTimeRecords()
        edit.Master.destroy()

    def OpenProjectListForm(self):
        projectListForm = ProjectListForm(self.Cache, self.dbConnection)
        projectListForm.Show()
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        projectListForm.Master.destroy()

    def OpenRecordTypeListForm(self):
        recordTypeListForm = RecordTypeListForm(self.Cache, self.dbConnection)
        recordTypeListForm.Show()
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        recordTypeListForm.Master.destroy()

    def ExportToExcel(self):
        excel = ExportToExcelForm(self.dbConnection)
        excel.Show()
        excel.Master.destroy()

    def ExportToGraph(self):
        graph = ExportToGraphsForm(self.dbConnection, self.Cache)
        graph.Show()
        graph.Master.destroy()

    def DeleteRecord(self):
        bl = BLTimeRecord.BLTimeRecord(self.dbConnection)
        indexRecordsListBox = self.RecordsListBox.curselection()[0]
        record = self.Cache.TimeRecordViews[indexRecordsListBox]
        bl.DeleteByID(record.ID)
        index = self.DaysCombo.current()
        self.Cache.RefreshAllStaticData()
        self.FillCombos()
        #Hier schiet nog 1 record over; het is nog niet verwijderd uit Cache op dit moment
        if len(self.Cache.TimeRecordViews) == 1:
            self.DaysCombo.set('')
        else:
            self.DaysCombo.current(index)
        self.RefreshTimeRecords()
        self.SetButtonsEnabled()

    def SetButtonsEnabled(self):
        enableStop = True
        enableCopyToCodex = True
        enableDelete = True
        enableCopyRecord = True
        enableOpenOneNote = True
        indexDaysCombo = self.DaysCombo.current()
        indexRecordsListBox = self.RecordsListBox.curselection()
        current = Globals.GetCurrentDay()
        if indexDaysCombo == -1:
            enableStop = False
            enableCopyToCodex = False
        else:
            date = self.Cache.DayViews[indexDaysCombo].Date
            if not current == date:
                enableStop = False
            bl = BLTimeRecord.BLTimeRecord(self.dbConnection)
            records = bl.GetAllForDate(date)
            for record in records:
                if record.StatusID == TimeRecordStatusEnum.TimeRecordStatusEnum.Gestart.value:
                    enableCopyToCodex = False
        if len(indexRecordsListBox) == 0:
            enableStop = False
            enableDelete = False
            enableCopyRecord = False
            enableOpenOneNote = False
        else:
            trView = self.Cache.TimeRecordViews[indexRecordsListBox[0]]
            if trView.OneNoteLink == 'None' or trView.OneNoteLink == "":
                enableOpenOneNote = False

        self.SetButton(enableStop, self.StopRecordButton)
        self.SetButton(enableCopyToCodex, self.CopyToCodexButton)
        self.SetButton(enableDelete, self.DeleteRecordButton)
        self.SetButton(enableCopyRecord, self.CopyRecordButton)
        self.SetButton(enableOpenOneNote, self.OneNoteButton)

    def SetButton(self, enabled, button):
        if enabled:
            button.config(state=NORMAL)
        else:
            button.config(state=DISABLED)
class OutletSelection(Frame):
    def __init__(self, root):
        Frame.__init__(self, root)

        self.rowconfigure(1, weight=1)
        self.columnconfigure(0, weight=1)

        ## Search bar

        search = Frame(self)
        search.grid(row=0, column=0, columnspan=2, padx=8)

        self.title = Label(search, text='Location: ').grid(row=0, column=0)

        self.outletVariable = StringVar(self)
        self.outletFilter = Entry(search, textvariable=self.outletVariable)
        self.outletFilter.grid(row=0, column=1, pady=10)
        self.outletFilter.bind('<Return>', lambda e: self._search_callback())

        self.searchButton = Button(search, text="Search", command=self._search_callback)
        self.searchButton.grid(row=0, column=2, padx=(8, 0))

        ## Results list

        # Listbox with search results
        self.outlets = Listbox(self, height=20, width=30)
        self.outlets.grid(row=1, column=0, sticky='nsew')
        self.outlets.bind('<<ListboxSelect>>', self._select_callback)

        # Y scrollbar
        self.yscrollbar = Scrollbar(self, orient="vertical")
        self.yscrollbar.config(command=self.outlets.yview)
        self.yscrollbar.grid(row=1, column=1, sticky="ns")
        self.outlets.config(yscrollcommand=self.yscrollbar.set)

        # X scrollbar
        self.xscrollbar = Scrollbar(self, orient="horizontal")
        self.xscrollbar.config(command=self.outlets.xview)
        self.xscrollbar.grid(row=2, column=0, sticky="ew")
        self.outlets.config(xscrollcommand=self.xscrollbar.set)

        self.locations = []

        ## Option to filter invalid locations

        toggle = Frame(self)
        toggle.grid(row=3, column=0, sticky='w')

        Label(toggle, text='Hide invalid locations').grid(row=0, column=0)

        self.filterInvalid = IntVar(self)
        self.filterInvalid.set(0)
        Checkbutton(toggle,
            variable=self.filterInvalid, command=self._search_callback
        ).grid(row=0, column=1, sticky='w')

        self.refresh()

    def refresh(self):
        '''Refresh the search content'''
        self.outletVariable.set('')
        self._search_callback()

    def _select_callback(self, event):
        '''Select the outlet to be used for creating a projection'''
        if len(self.locations) == 0:
            return

        widget = event.widget
        selection = widget.curselection()
        location = self.locations[selection[0]]

        pInputs = gb.main_window.getComponent(GUI.projectionInputs)
        pInputs.setOutlet(location.get_abbreviation())

    def _search_callback(self):
        '''Get and display the relevant search results'''
        self.outlets.delete(0, END)

        t = str(self.outletVariable.get())
        self.locations = location.search_locations(t)

        if self.filterInvalid.get():
            rm = []
            for loc in self.locations:
                if not loc.get_valid():
                    rm.append(loc)
            for loc in rm:
                self.locations.remove(loc)

        for i in range(len(self.locations)):
            loc = self.locations[i]
            self.outlets.insert(END, loc)
            if not loc.get_valid():
                self.outlets.itemconfig(i, selectbackground='grey80', selectforeground='grey', fg='grey80')
Exemplo n.º 24
0
class LabelTool():
    """Simple YOLO format annotation tool based on tkinter"""
    def __init__(self, master):
        # set up the main frame
        self.cur_cls_id = -1
        self.parent = master
        self.parent.title("Yolo Annotation Tool")
        self.frame = Frame(self.parent)
        self.frame.pack(fill=BOTH, expand=1)
        self.parent.resizable(width=False, height=False)

        # initialise global state
        self.imageDir = ''
        self.imageList = []
        self.egDir = ''
        self.egList = []
        self.outDir = ''
        self.cur = 0
        self.total = 0
        self.category = 0
        self.imagename = ''
        self.labelfilename = ''
        self.tkimg = None
        self.img = None
        self.classes = []

        # initialise mouse state
        self.STATE = {}
        self.STATE['click'] = 0
        self.STATE['x'], self.STATE['y'] = 0, 0

        # reference to bbox
        self.bboxIdList = []
        self.bboxId = None
        self.bboxList = []
        self.bboxListCls = []
        self.hl = None
        self.vl = None

        # ----------------- GUI thing ---------------------
        # dir entry & load
        self.label = Label(self.frame, text="Image Dir:")
        self.label.grid(row=0, column=0, sticky=E)
        self.entry = Entry(self.frame)
        # self.entry.focus_set()
        #self.entry.bind('<Return>', self.loadEntry)
        self.entry.grid(row=0, column=1, sticky=W + E)
        self.ldBtn = Button(self.frame,
                            text="Load",
                            command=self.load_dir_dialog)
        self.ldBtn.grid(row=0, column=2, sticky=W + E)

        # main panel for labelling
        self.mainPanel = Canvas(self.frame, cursor='tcross')
        self.mainPanel.bind("<Button-1>", self.mouse_click)
        self.mainPanel.bind("<Motion>", self.mouse_move)
        self.mainPanel.bind("<Configure>", self.resize_image_event)
        self.parent.bind(
            "<Escape>",
            self.cancel_bbox)  # press <Espace> to cancel current bbox
        self.parent.bind("s", self.cancel_bbox)
        self.parent.bind("<Left>",
                         self.previous_image)  # press 'a' to go backforward
        self.parent.bind("<Right>", self.next_image)  # press 'd' to go forward
        self.mainPanel.grid(row=1, column=1, rowspan=4, sticky=W + N)

        # showing bbox info & delete bbox
        self.tkvar = StringVar(self.parent)
        self.cur_cls_id = 0
        self.popupMenu = OptionMenu(self.frame, self.tkvar, "None")
        self.popupMenu.grid(row=1, column=2, sticky=E + S)
        self.chooselbl = Label(self.frame, text='Choose Class:')
        self.chooselbl.grid(row=1, column=2, sticky=W + S)
        self.lb1 = Label(self.frame, text='Bounding boxes:')
        self.lb1.grid(row=2, column=2, sticky=W + N)
        self.listbox = Listbox(self.frame, width=30, height=12)
        self.listbox.grid(row=3, column=2, sticky=N)
        self.btnDel = Button(self.frame,
                             text='Delete',
                             command=self.delete_bbox)
        self.btnDel.grid(row=4, column=2, sticky=W + E + N)
        self.btnClear = Button(self.frame,
                               text='ClearAll',
                               command=self.clear_all_bbox)
        self.btnClear.grid(row=5, column=2, sticky=W + E + N)

        # control panel for image navigation
        self.ctrPanel = Frame(self.frame)
        self.ctrPanel.grid(row=6, column=1, columnspan=2, sticky=W + E)
        self.prevBtn = Button(self.ctrPanel,
                              text='<< Prev',
                              width=10,
                              command=self.previous_image)
        self.prevBtn.pack(side=LEFT, padx=5, pady=3)
        self.nextBtn = Button(self.ctrPanel,
                              text='Next >>',
                              width=10,
                              command=self.next_image)
        self.nextBtn.pack(side=LEFT, padx=5, pady=3)
        self.progLabel = Label(self.ctrPanel, text="Progress:     /    ")
        self.progLabel.pack(side=LEFT, padx=5)
        self.tmpLabel = Label(self.ctrPanel, text="Go to Image No.")
        self.tmpLabel.pack(side=LEFT, padx=5)
        self.idxEntry = Entry(self.ctrPanel, width=5)
        self.idxEntry.pack(side=LEFT)
        self.goBtn = Button(self.ctrPanel, text='Go', command=self.goto_image)
        self.goBtn.pack(side=LEFT)

        # example pannel for illustration
        self.egPanel = Frame(self.frame, border=10)
        self.egPanel.grid(row=1, column=0, rowspan=5, sticky=N)
        self.tmpLabel2 = Label(self.egPanel, text="Examples:")
        self.tmpLabel2.pack(side=TOP, pady=5)
        self.egLabels = []
        for _ in range(3):
            self.egLabels.append(Label(self.egPanel))
            self.egLabels[-1].pack(side=TOP)

        # display mouse position
        self.disp = Label(self.ctrPanel, text='')
        self.disp.pack(side=RIGHT)

        self.frame.columnconfigure(1, weight=1)
        self.frame.rowconfigure(4, weight=1)

    def load_dir_dialog(self):
        """Open a directory browsing dialog to select a dataset within ./Images to annotate"""
        dirpath = filedialog.askdirectory()
        if dirpath:
            # Make dirpath relative to images directory
            subdir_path = Path(dirpath)
            if IMAGES_ROOT not in subdir_path.parents:
                tkMessageBox.showerror(
                    "Error!",
                    message="The directory should be within {0}".format(
                        IMAGES_ROOT))
                return

            self.entry.delete(0, END)
            self.entry.insert(0, str(subdir_path.relative_to(IMAGES_ROOT)))
            self.load_dir()

    def load_classes(self):
        """Load dataset specific classes, if do not exist fallback to defaults"""
        try:
            print(IMAGES_ROOT)
            print(self.category)
            print(CLASSES_FILENAME)
            classes_fullpath = os.path.join(IMAGES_ROOT, self.category,
                                            CLASSES_FILENAME)
            if os.path.exists(classes_fullpath):
                print("Loading dataset specific classes file {0}".format(
                    classes_fullpath))
            else:
                print("No dataset classes file {0}, loading default".format(
                    classes_fullpath))
                classes_fullpath = CLASSES_FILENAME

            with open(classes_fullpath, 'r') as cls:
                classes = cls.readlines()
            self.classes = [cls.strip() for cls in classes]

            menu = self.popupMenu["menu"]
            menu.delete(0, "end")
            for cls in self.classes:
                menu.add_command(label=cls,
                                 command=lambda v=cls: self.change_dropdown(v))
            self.tkvar.set(self.classes[0])

        except IOError:
            print("[ERROR] Please create {0} and put your all classes".format(
                classes_fullpath))
            sys.exit(1)
        assert len(self.classes) <= len(COLOURS)

    def load_dir(self, dbg=False):
        """Load annotation dataset in selected sub directory"""
        if not dbg:
            try:
                subdir = self.entry.get()
                self.parent.focus()
                self.category = subdir
            except ValueError:
                tkMessageBox.showerror("Error!",
                                       message="The folder should be numbers")
                return
        if not os.path.isdir(os.path.join(IMAGES_ROOT, self.category)):
            tkMessageBox.showerror("Error!",
                                   message="The specified dir doesn't exist!")
            return
        # get image list
        self.imageDir = os.path.join(IMAGES_ROOT, self.category)
        self.imageList = [
            file for imageType in SUPPORTED_IMAGE_TYPES
            for file in glob.glob(os.path.join(self.imageDir, imageType))
        ]
        if len(self.imageList) == 0:
            tkMessageBox.showerror(
                "Error!",
                message="No {0} images found in the specified dir!".format(
                    SUPPORTED_IMAGE_TYPES))
            return

        # default to the 1st image in the collection
        self.cur = 1
        self.total = len(self.imageList)

        self.load_classes()

        # set up output dir
        if not os.path.exists('./Labels'):
            os.mkdir('./Labels')
        self.outDir = os.path.join(r'./Labels', '%s' % (self.category))
        if not os.path.exists(self.outDir):
            os.mkdir(self.outDir)
        self.load_image()
        print('%d images loaded from %s' % (self.total, self.category))

    def load_image(self):
        """Load the current image into the canvas and render any existing labels"""
        # load image
        imagepath = self.imageList[self.cur - 1]
        self.img = PImage.open(imagepath)
        self.tkimg = ImageTk.PhotoImage(self.img)
        self.mainPanel.config(width=max(self.tkimg.width(), 400),
                              height=max(self.tkimg.height(), 400))
        self.mainPanel.create_image(0,
                                    0,
                                    image=self.tkimg,
                                    anchor=NW,
                                    tags="IMG")
        self.progLabel.config(text="%04d/%04d" % (self.cur, self.total))

        self.mainPanel.update()
        self.resize_image(self.mainPanel.winfo_width(),
                          self.mainPanel.winfo_height())

        # load labels
        self.clear_all_bbox()
        # self.imagename = os.path.split(imagepath)[-1].split('.')[0]
        self.imagename = os.path.splitext(os.path.basename(imagepath))[0]
        labelname = self.imagename + '.txt'
        self.labelfilename = os.path.join(self.outDir, labelname)
        if os.path.exists(self.labelfilename):
            with open(self.labelfilename) as label_file:
                for line in label_file:
                    yolo_data = line.strip().split()
                    tl_br_bbox = yolo_bbox_to_tl_br_bbox(
                        [float(data) for data in yolo_data[1:]])
                    self.bboxList.append(tl_br_bbox)
                    self.bboxListCls.append(yolo_data[0])

                    abs_bbox = rel_bbox_to_abs_bbox(
                        tl_br_bbox, (self.tkimg.width(), self.tkimg.height()))
                    tmpId = self.mainPanel.create_rectangle(
                        abs_bbox[0],
                        abs_bbox[1],
                        abs_bbox[2],
                        abs_bbox[3],
                        width=2,
                        outline=COLOURS[int(yolo_data[0])])
                    self.bboxIdList.append(tmpId)
                    self.listbox.insert(
                        END, '(%.2f, %.2f) -> (%.2f, %.2f) -> (%s)' %
                        (tl_br_bbox[0], tl_br_bbox[1], tl_br_bbox[2],
                         tl_br_bbox[3], self.classes[int(yolo_data[0])]))
                    self.listbox.itemconfig(len(self.bboxIdList) - 1,
                                            fg=COLOURS[int(yolo_data[0])])

    def resize_image(self, width, height):
        """Resize the current image to fit the canvas"""
        if self.tkimg:
            size = (width, height)
            resized = self.img.resize(size, PImage.ANTIALIAS)
            self.tkimg = ImageTk.PhotoImage(resized)
            self.mainPanel.delete("IMG")
            self.mainPanel.create_image(0,
                                        0,
                                        image=self.tkimg,
                                        anchor=NW,
                                        tags="IMG")
            self.bboxIdList.clear()
            for tl_br_bbox, bboxcls in zip(self.bboxList, self.bboxListCls):
                abs_bbox = rel_bbox_to_abs_bbox(
                    tl_br_bbox, (self.tkimg.width(), self.tkimg.height()))
                tmpId = self.mainPanel.create_rectangle(
                    abs_bbox[0],
                    abs_bbox[1],
                    abs_bbox[2],
                    abs_bbox[3],
                    width=2,
                    outline=COLOURS[int(bboxcls)])
                self.bboxIdList.append(tmpId)

    def resize_image_event(self, event):
        """Resize the current image to fit the canvas"""
        self.resize_image(event.width, event.height)

    def save_image_labels(self):
        """Save labels for current image to disk"""
        with open(self.labelfilename, 'w') as f:
            for tl_br_bbox, bboxcls in zip(self.bboxList, self.bboxListCls):
                yolo_bbox = tl_br_bbox_to_yolo_bbox(tl_br_bbox)
                f.write(
                    str(bboxcls) + " " + " ".join([str(a)
                                                   for a in yolo_bbox]) + '\n')
        print('Image No. %d saved' % (self.cur))

    def mouse_click(self, event):
        """On mouse click event finalise and save bounding box"""
        if self.tkimg:
            if self.STATE['click'] == 0:
                self.STATE['x'], self.STATE['y'] = event.x, event.y
            else:
                tl_x = min(self.STATE['x'], event.x) / self.tkimg.width()
                br_x = max(self.STATE['x'], event.x) / self.tkimg.width()
                tl_y = min(self.STATE['y'], event.y) / self.tkimg.height()
                br_y = max(self.STATE['y'], event.y) / self.tkimg.height()
                self.bboxList.append((tl_x, tl_y, br_x, br_y))
                self.bboxListCls.append(self.cur_cls_id)
                self.bboxIdList.append(self.bboxId)
                self.bboxId = None
                self.listbox.insert(
                    END, '(%.2f, %.2f) -> (%.2f, %.2f) -> (%s)' %
                    (tl_x, tl_y, br_x, br_y, self.classes[self.cur_cls_id]))
                self.listbox.itemconfig(len(self.bboxIdList) - 1,
                                        fg=COLOURS[self.cur_cls_id])
            self.STATE['click'] = 1 - self.STATE['click']

    def mouse_move(self, event):
        """On mouse move event continually update shape of bounding box"""
        if self.tkimg:
            self.disp.config(
                text='x: %.2f, y: %.2f' %
                (event.x / self.tkimg.width(), event.y / self.tkimg.height()))
            if self.tkimg:
                if self.hl:
                    self.mainPanel.delete(self.hl)
                self.hl = self.mainPanel.create_line(0,
                                                     event.y,
                                                     self.tkimg.width(),
                                                     event.y,
                                                     width=2)
                if self.vl:
                    self.mainPanel.delete(self.vl)
                self.vl = self.mainPanel.create_line(event.x,
                                                     0,
                                                     event.x,
                                                     self.tkimg.height(),
                                                     width=2)
            if self.STATE['click'] == 1:
                if self.bboxId:
                    self.mainPanel.delete(self.bboxId)
                self.bboxId = self.mainPanel.create_rectangle(
                    self.STATE['x'],
                    self.STATE['y'],
                    event.x,
                    event.y,
                    width=2,
                    outline=COLOURS[self.cur_cls_id])

    def cancel_bbox(self, event):
        """On cancel bbox event (HIT ESCAPE DURING SELECTION) reset active selection bounding box"""
        if self.STATE['click'] == 1:
            if self.bboxId:
                self.mainPanel.delete(self.bboxId)
                self.bboxId = None
                self.STATE['click'] = 0

    def delete_bbox(self):
        """On delete bounding box event (DELETE BUTTON CLICK), delete selected bounding box"""
        sel = self.listbox.curselection()
        if len(sel) != 1:
            return
        idx = int(sel[0])
        self.mainPanel.delete(self.bboxIdList[idx])
        self.bboxIdList.pop(idx)
        self.bboxList.pop(idx)
        self.bboxListCls.pop(idx)
        self.listbox.delete(idx)

    def clear_all_bbox(self):
        """On clear all bounding box event (CLEAR ALL BUTTON CLICK), remove ALL bounding boxes"""
        for idx in range(len(self.bboxIdList)):
            self.mainPanel.delete(self.bboxIdList[idx])
        self.listbox.delete(0, len(self.bboxList))
        self.bboxIdList = []
        self.bboxList = []
        self.bboxListCls = []

    def previous_image(self, event=None):
        """Load previous image in annotation queue"""
        self.save_image_labels()
        if self.cur > 1:
            self.cur -= 1
            self.load_image()
        else:
            tkMessageBox.showerror("Information!",
                                   message="This is first image")

    def next_image(self, event=None):
        """Load next image in annotation queue"""
        self.save_image_labels()
        if self.cur < self.total:
            self.cur += 1
            self.load_image()
        else:
            tkMessageBox.showerror("Information!",
                                   message="All images annotated")

    def goto_image(self):
        """Go to specific image in annotation queue"""
        idx = int(self.idxEntry.get())
        if 1 <= idx <= self.total:
            self.save_image_labels()
            self.cur = idx
            self.load_image()

    def change_dropdown(self, cls):
        """Update currently selected annotation class from dropdown selection"""
        self.tkvar.set(cls)
        self.cur_cls_id = self.classes.index(cls)
Exemplo n.º 25
0
class AddProducts:
    def __init__(self, service, top_level):
        self.service = service
        self.top_level = top_level
        # Gui elements
        self.name_entry = None
        self.shops_combo = None
        self.category_combo = None
        self.search_button = None
        self.listbox = None
        # Last searched products list
        self.products_found = None  # List
        self.products_found_positions = None  # Dictionary
        self.existing = None  # Set
        self.init_gui()

    def init_gui(self):
        self.top_level.geometry("600x750")

        self.name_entry = Entry(self.top_level)
        self.name_entry.grid(row=0, column=0, columnspan=2, sticky=W + E)
        self.name_entry.insert(0, 'Product name')
        self.name_entry.bind("<FocusIn>",
                             lambda args: self.name_entry.delete('0', 'end'))

        # shop_choices = ['Emag', 'Altex', 'Media Galaxy']
        shop_choices = ['Emag']
        self.shops_combo = Combobox(self.top_level, values=shop_choices)
        self.shops_combo.grid(row=1, column=0, sticky=W + E)
        self.shops_combo.current(0)

        # Make it configurable from config file
        category_choices = [
            'Laptops', 'Phones', 'Tablets', 'Tvs', 'Portable speakers',
            'Headphones', 'Consoles'
        ]
        self.category_combo = Combobox(self.top_level, values=category_choices)
        self.category_combo.grid(row=1, column=1, sticky=W + E)
        self.category_combo.current(0)

        # Search bu
        self.search_button = Button(self.top_level,
                                    text='Search',
                                    command=self.on_search_event)
        self.search_button.grid(row=2,
                                column=0,
                                columnspan=2,
                                sticky=W + E + S + N)

        # Frame to encapsulate the listbox and scrollbar
        frame = Frame(self.top_level, bd=2, relief=SUNKEN)

        scrollbar = Scrollbar(frame)
        scrollbar.pack(side=RIGHT, fill=Y)

        self.listbox = Listbox(frame, bd=0, yscrollcommand=scrollbar.set)

        self.listbox.bind('<Double-Button-1>', self.on_product_inspect)
        self.listbox.bind('<Return>', self.on_product_inspect)

        self.listbox.pack(fill=BOTH, expand=1)
        frame.grid(row=3, column=0, columnspan=2, sticky=W + E + N + S)

        scrollbar.config(command=self.listbox.yview)

        for x in range(3):
            Grid.rowconfigure(self.top_level, x, pad=10)
        Grid.rowconfigure(self.top_level, 3, weight=1)
        for x in range(2):
            Grid.columnconfigure(self.top_level, x, weight=1)

    def on_product_inspect(self, event):
        w = event.widget
        index = int(w.curselection()[0])

        new_win = Toplevel(self.top_level)
        ex = ExamineNewProduct(self.service, self.products_found[index],
                               new_win)

        self.service.add_observer(ex, Events.NEW_P)
        new_win.protocol("WM_DELETE_WINDOW",
                         lambda: self.destroy_examination(ex, new_win))

    def destroy_examination(self, ex, new_win):
        self.service.remove_observer(ex, Events.NEW_P)
        new_win.destroy()

    def on_search_event(self):
        self.products_found = self.service.search_products(
            self.name_entry.get(), self.category_combo.get(), 'Emag')
        if self.products_found is None:
            return
        self.listbox.delete(0, 'end')
        self.products_found_positions = {}
        self.existing = set()
        for index, product in enumerate(self.products_found):
            self.listbox.insert(END, product.title)
            self.products_found_positions[product.id] = index
            if self.service.product_already_exists(product.id):
                self.listbox.itemconfig(index, foreground='orange')
                self.existing.add(product.id)

    def update(self, data, event):
        if event == Events.NEW_P:
            id = data
            if self.products_found_positions is not None and id in self.products_found_positions:
                index = self.products_found_positions[id]
                self.listbox.itemconfig(index, foreground='orange')
Exemplo n.º 26
0
class ListboxVidget(Vidget, Eventor):
    """
    ListboxVidget contains a Listbox widget. It adds the following abilities:
    - Store items of any type, unlike Listbox widget that only stores texts.
    - Remember selected item even if the listbox widget lost focus.
    - Notify pre-change and post-change events.
    """

    # Error raised when trying to change the listbox while a change is going on
    class CircularCallError(ValueError):
        pass

    # Error raised when trying to change the listbox while it is disabled
    class DisabledError(ValueError):
        pass

    # Event notified when the listbox's items are to be changed
    ITEMS_CHANGE_SOON = 'ITEMS_CHANGE_SOON'

    # Event notified when the listbox's items are changed
    ITEMS_CHANGE_DONE = 'ITEMS_CHANGE_DONE'

    # Event notified when the listbox's active item is to be changed
    ITEMCUR_CHANGE_SOON = 'ITEMCUR_CHANGE_SOON'

    # Event notified when the listbox's active item is changed
    ITEMCUR_CHANGE_DONE = 'ITEMCUR_CHANGE_DONE'

    # Events list
    EVENTS = (
        ITEMS_CHANGE_SOON,
        ITEMS_CHANGE_DONE,
        ITEMCUR_CHANGE_SOON,
        ITEMCUR_CHANGE_DONE,
    )

    def __init__(
        self,
        items=None,
        item_to_text=None,
        normal_bg='',
        normal_fg='',
        active_bg='sky blue',
        active_fg='white',
        selected_bg='steel blue',
        selected_fg='white',
        master=None,
    ):
        """
        Initialize object.

        @param items: Items list.

        @param item_to_text: Item-to-text function. Default is `str`.

        @param normal_bg: Unselected item background color.

        @param normal_fg: Unselected item foreground color.

        @param active_bg: Active item background color. `Active` means the item
        is selected (in general meaning) but the listbox has no focus.

        @param active_fg: Active item foreground color. `Active` means the item
        is selected (in general meaning) but the listbox has no focus.

        @param selected_bg: Selected item background color. `Selected` means
        the item is selected (in general meaning) and the listbox has focus.

        @param selected_fg: Selected item foreground color. `Selected` means
        the item is selected (in general meaning) and the listbox has focus.

        @param master: Master widget.

        @return: None.
        """
        # Initialize Vidget.
        # Create main frame widget.
        Vidget.__init__(
            self,
            master=master,
        )

        # Initialize Eventor
        Eventor.__init__(self)

        # If items list is given
        if items is not None:
            # If items list is not list
            if not isinstance(items, list):
                # Raise error
                raise TypeError(items)

            # If items list is list.

        # If items list is not given, or items list is given and is list

        # Items list
        self._items = items if items is not None else []

        # Item-to-text function. Default is `str`.
        self._item_to_text = item_to_text if item_to_text is not None else str

        # Unselected item background color
        self._normal_fg = normal_fg

        # Unselected item foreground color
        self._normal_bg = normal_bg

        # Active item background color
        self._active_fg = active_fg

        # Active item foreground color
        self._active_bg = active_bg

        # Selected item background color
        self._selected_fg = selected_fg

        # Selected item foreground color
        self._selected_bg = selected_bg

        # Whether the listbox is changing
        self._is_changing = False

        # Active index. `-1` means void, i.e. no item is active.
        self._indexcur = -1

        # Whether active index is being reset to same value
        self._is_resetting = False

        # Create listbox widget
        self._listbox = Listbox(
            master=self.widget(),
            relief='groove',
            activestyle='none',
            highlightthickness=0,
            # Active index cache only supports single-selection mode for now.
            # See 2N6OR.
            selectmode='single',
        )

        # Set the listbox widget as config target
        self.config_target_set(self._listbox)

        # Create x-axis scrollbar
        self._scrollbar_xview = _HiddenScrollbar(
            self.widget(),
            orient=HORIZONTAL,
        )

        # Create y-axis scrollbar
        self._scrollbar_yview = _HiddenScrollbar(
            self.widget(),
            orient=VERTICAL,
        )

        # Mount scrollbars
        self._listbox.config(xscrollcommand=self._scrollbar_xview.set)

        self._listbox.config(yscrollcommand=self._scrollbar_yview.set)

        self._scrollbar_xview.config(command=self._listbox.xview)

        self._scrollbar_yview.config(command=self._listbox.yview)

        # Bind single-click event handler
        self._listbox.bind('<Button-1>', self._on_single_click)

        # Bind double-click event handler
        self._listbox.bind('<Double-Button-1>', self._on_double_click)

        # Update listbox widget
        self._listbox_widget_update(keep_active=False)

        # Update widget
        self._widget_update()

    def _widget_update(self):
        """
        Update widget.

        @return: None.
        """
        # Row 0 for listbox and y-axis scrollbar
        self.widget().rowconfigure(0, weight=1)

        # Row 1 for x-axis scrollbar
        self.widget().rowconfigure(1, weight=0)

        # Column 0 for listbox and x-axis scrollbar
        self.widget().columnconfigure(0, weight=1)

        # Column 1 for y-axis scrollbar
        self.widget().columnconfigure(1, weight=0)

        # Lay out listbox
        self._listbox.grid(row=0, column=0, sticky='NSEW')

        # Lay out x-axis scrollbar
        self._scrollbar_xview.grid(row=1, column=0, sticky='EW')

        # Lay out y-axis scrollbar
        self._scrollbar_yview.grid(row=0, column=1, sticky='NS')

    def is_enabled(self):
        """
        Test whether the listbox is enabled.

        @return: Boolean.
        """
        # Return whether the listbox is enabled
        return self._listbox.config('state')[4] != DISABLED

    def is_changing(self):
        """
        Test whether the listbox is changing.

        @return: Boolean.
        """
        # Return whether the listbox is changing
        return self._is_changing

    def is_resetting(self):
        """
        Test whether the listbox is setting active index to the same value.

        @return: Boolean.
        """
        # Return whether the listbox is setting active index to the same value
        return self._is_resetting

    def size(self):
        """
        Get number of items.

        @return: Number of items.
        """
        # Return number of items
        return len(self._items)

    def items(self):
        """
        Get items list.
        Notice do not change the list outside.

        @return: Items list.
        """
        # Return items list
        return self._items

    def items_set(
        self,
        items,
        notify=True,
        keep_active=False,
    ):
        """
        Set items list.

        Notice do not change the list outside.

        @param items: Items list.

        @param notify: Whether notify pre-change and post-change events.

        @param keep_active: Whether keep or clear active index.

        @return: None.
        """
        # If the items is not list
        if not isinstance(items, list):
            # Raise error
            raise TypeError(items)

        # If the items is list.

        # If the listbox is disabled
        if not self.is_enabled():
            # Raise error
            raise ListboxVidget.DisabledError()

        # If the listbox is not disabled.

        # If the listbox is changing
        if self._is_changing:
            # Raise error
            raise ListboxVidget.CircularCallError()

        # If the listbox is not changing.

        # Set changing flag on
        self._is_changing = True

        # If notify events
        if notify:
            # Notify pre-change event
            self.handler_notify(self.ITEMS_CHANGE_SOON)

        # Store the new items
        self._items = items

        # Update listbox widget
        self._listbox_widget_update(
            keep_active=keep_active
        )

        # If notify events
        if notify:
            # Notify post-change event
            self.handler_notify(self.ITEMS_CHANGE_DONE)

        # Set changing flag off
        self._is_changing = False

    def index_is_valid(self, index):
        """
        Test whether given index is valid. Notice -1 is not valid.

        @param index: Index to test.

        @return: Boolean.
        """
        # Test whether given index is valid
        return 0 <= index and index < self.size()

    def index_is_valid_or_void(self, index):
        """
        Test whether given index is valid or is -1.

        @param index: Index to test.

        @return: Boolean.
        """
        # Test whether given index is valid or is -1
        return index == -1 or self.index_is_valid(index)

    def index_first(self):
        """
        Get the first item's index.

        @return: First item's index, or -1 if the listbox is empty.
        """
        # Return the first item's index
        return 0 if self.size() > 0 else -1

    def index_last(self):
        """
        Get the last item's index.

        @return: Last item's index, or -1 if the listbox is empty.
        """
        # Return the last item's index
        return self.size() - 1

    def indexcur(self, internal=False, raise_error=False):
        """
        Get the active index.

        @param internal: See 2N6OR.

        @return: The active index. If no active active, either return -1, or
        raise IndexError if `raise_error` is True.
        """
        # Get active indexes
        indexcurs = self._indexcurs(internal=internal)

        # If have active indexes
        if indexcurs:
            # Return the first active index
            return indexcurs[0]

        # If no active indexes
        else:
            # If raise error
            if raise_error:
                # Raise error
                raise IndexError(-1)

            # If not raise error
            else:
                # Return -1
                return -1

    def _indexcurs(self, internal=False):
        """
        Get active indexes list.

        2N6OR
        @param internal: Whether use listbox widget's selected indexes, instead
        of cached active index.
        Notice listbox widget has no selected indexes if it has no focus.
        Notice using cached active index only supports single-selection mode,
        which means the result list has at most one index.

        @return: Active indexes list.
        """
        # If use listbox widget's selected indexes
        if internal:
            # Return listbox widget's selected indexes list
            return [int(x) for x in self._listbox.curselection()]

        # If not use listbox widget's selected indexes
        else:
            # If cached active index is valid
            if self.index_is_valid(self._indexcur):
                # Return a list with the cached active index
                return [self._indexcur]

            # If cached active index is not valid
            else:
                # Return empty list
                return []

    def indexcur_set(
        self,
        index,
        focus=False,
        notify=True,
        notify_arg=None,
    ):
        """
        Set active index.

        @param index: The index to set.

        @param focus: Whether set focus on the listbox widget.

        @param notify: Whether notify pre-change and post-change events.

        @param notify_arg: Event argument.

        @return: None.
        """
        # If the index is not valid or -1
        if not self.index_is_valid_or_void(index):
            # Raise error
            raise IndexError(index)

        # If the index is valid or is -1.

        # If the listbox is not enabled
        if not self.is_enabled():
            # Raise error
            raise ListboxVidget.DisabledError()

        # If the listbox is enabled.

        # If the listbox is changing
        if self._is_changing:
            # Raise error
            raise ListboxVidget.CircularCallError()

        # If the listbox is not changing.

        # Set changing flag on
        self._is_changing = True

        # Get old active index
        old_indexcur = self._indexcur

        # Set resetting flag on if new and old indexes are equal
        self._is_resetting = (index == old_indexcur)

        # If notify events
        if notify:
            # Notify pre-change event
            self.handler_notify(self.ITEMCUR_CHANGE_SOON, notify_arg)

        # If old active index is valid
        if self.index_is_valid(old_indexcur):
            # Set old active item's background color to normal color
            self._listbox.itemconfig(old_indexcur, background=self._normal_bg)

            # Set old active item's foreground color to normal color
            self._listbox.itemconfig(old_indexcur, foreground=self._normal_fg)

        # Cache new active index
        self._indexcur = index

        # Clear listbox widget's selection
        self._listbox.selection_clear(0, END)

        # Set listbox widget's selection
        self._listbox.selection_set(index)

        # Set listbox widget's activated index
        self._listbox.activate(index)

        # If new active index is valid
        if index != -1:
            # Set new active item's background color to active color
            self._listbox.itemconfig(index, background=self._active_bg)

            # Set new active item's foreground color to active color
            self._listbox.itemconfig(index, foreground=self._active_fg)

        # If set focus
        if focus:
            # Set focus on the listbox widget
            self._listbox.focus_set()

        # If new active index is valid
        if index != -1:
            # Make the active item visible
            self._listbox.see(index)

        # If notify events
        if notify:
            # Notify post-change event
            self.handler_notify(self.ITEMCUR_CHANGE_DONE, notify_arg)

        # Set resetting flag off
        self._is_resetting = False

        # Set changing flag off
        self._is_changing = False

    def indexcur_set_by_event(
        self,
        event,
        focus=False,
        notify=True,
        notify_arg=None,
    ):
        """
        Set active index using a Tkinter event object that contains coordinates
        of the active item.

        @param event: Tkinter event object.

        @param focus: Whether set focus on the listbox widget.

        @param notify: Whether notify pre-change and post-change events.

        @param notify_arg: Event argument.

        @return: None.
        """
        # Get the event's y co-ordinate's nearest listbox item index
        index = self._listbox.nearest(event.y)

        # If the index is not valid
        if not self.index_is_valid_or_void(index):
            # Ignore the event
            return

        # If the index is valid
        else:
            # Set the index as active index
            self.indexcur_set(
                index=index,
                focus=focus,
                notify=notify,
                notify_arg=notify_arg,
            )

    def item(self, index):
        """
        Get item at given index.

        @return: Item at given index, or IndexError if the index is not valid.
        """
        return self.items()[index]

    def itemcur(self, internal=False, raise_error=False):
        """
        Get the active item.

        @param internal: See 2N6OR.

        @param raise_error: Whether raise error if no active item.

        @return: The active item. If no active item, if `raise_error` is
        True, raise IndexError, otherwise return None.
        """
        # Get active index.
        # May raise IndexError if `raise_error` is True.
        indexcur = self.indexcur(
            internal=internal,
            raise_error=raise_error,
        )

        # If no active index
        if indexcur == -1:
            # Return None
            return None

        # If have active index
        else:
            # Return the active item
            return self.items()[indexcur]

    def item_insert(
        self,
        item,
        index=None,
        notify=True,
        keep_active=True,
    ):
        """
        Insert item at given index.

        @param item: Item to insert.

        @param index: Index to insert. `None` means active index, and if no
        active index, insert at the end.

        @param notify: Whether notify pre-change and post-change events.

        @param keep_active: Whether keep or clear active index.

        @return: None.
        """
        # If notify events
        if notify:
            # Notify pre-change events
            self.handler_notify(self.ITEMCUR_CHANGE_SOON)

            self.handler_notify(self.ITEMS_CHANGE_SOON)

        # Get old active index
        active_index = self.indexcur()

        # If the index is None,
        # it means use active index.
        if index is None:
            # Use active index.
            # `-1` works and means appending.
            index = active_index

        # Insert the item to the items list
        self._items.insert(index, item)

        # If old active index is valid
        if active_index != -1:
            # If old active index is GE the inserted index
            if active_index >= index:
                # Shift active index by one
                active_index += 1

            # If old active index is not GE the inserted index, use it as-is.

        # Set new active index
        self.indexcur_set(index=active_index, notify=False)

        # Update listbox widget
        self._listbox_widget_update(
            keep_active=keep_active
        )

        # If notify events
        if notify:
            # Notify post-change events
            self.handler_notify(self.ITEMS_CHANGE_DONE)

            self.handler_notify(self.ITEMCUR_CHANGE_DONE)

    def item_remove(
        self,
        index,
        notify=True,
        keep_active=True,
    ):
        """
        Remove item at given index.

        @param index: Index to remove.

        @param notify: Whether notify pre-change and post-change events.

        @param keep_active: Whether keep or clear active index.

        @return: None.
        """
        # If the index is not valid
        if not self.index_is_valid(index):
            # Raise error
            raise ValueError(index)

        # If the index is valid.

        # If notify events
        if notify:
            # Notify pre-change events
            self.handler_notify(self.ITEMCUR_CHANGE_SOON)

            self.handler_notify(self.ITEMS_CHANGE_SOON)

        # Get old active index
        active_index = self.indexcur()

        # Remove item at the index
        del self._items[index]

        # If old active index is valid
        if active_index != -1:
            # Get the last index
            index_last = self.index_last()

            # If old active index is GT the last index
            if active_index > index_last:
                # Use the last index as new active index
                active_index = index_last

            # If old active index is not GT the last index, use it as-is.

        # Set new active index
        self.indexcur_set(index=active_index, notify=False)

        # Update listbox widget
        self._listbox_widget_update(
            keep_active=keep_active
        )

        # If notify events
        if notify:
            # Notify post-change events
            self.handler_notify(self.ITEMS_CHANGE_DONE)

            self.handler_notify(self.ITEMCUR_CHANGE_DONE)

    def handler_add(
        self,
        event,
        handler,
        need_arg=False,
    ):
        """
        Add event handler for an event.
        If the event is ListboxVidget event, add the event handler to Eventor.
        If the event is not ListboxVidget event, add the event handler to
        listbox widget.

        Notice this method overrides `Eventor.handler_add` in order to add
        non-ListboxVidget event handler to listbox widget.

        @param event: Event name.

        @param handler: Event handler.

        @param need_arg: Whether the event handler needs event argument.

        @return: None.
        """
        # If the event is ListboxVidget event
        if event in self.EVENTS:
            # Add the event handler to Eventor
            return Eventor.handler_add(
                self,
                event=event,
                handler=handler,
                need_arg=need_arg,
            )

        # If the event is not ListboxVidget event,
        # it is assumed to be Tkinter widget event.
        else:
            # Add the event handler to listbox widget
            return self.bind(
                event=event,
                handler=handler,
            )

    def bind(
        self,
        event,
        handler,
    ):
        """
        Add event handler to listbox widget.

        ListboxVidget internally uses `<Button-1>` and `<Double-Button-1>` to
        capture active index changes. So if the given event is `<Button-1>` or
        `<Double-Button-1>`, the given handler will be wrapped.

        @param event: Event name.

        @param handler: Event handler.

        @return: None.
        """
        # If the event is not `<Button-1>` or `<Double-Button-1>`
        if event not in ['<Button-1>', '<Double-Button-1>']:
            # Add the event handler to listbox widget
            self._listbox.bind(event, handler)

        # If the event is `<Button-1>` or `<Double-Button-1>`
        else:
            # Create event handler wrapper
            def handler_wrapper(e):
                """
                Event handler wrapper that sets new active index and then calls
                the wrapped event handler.

                Setting new active index is needed because when this handler is
                called by Tkinter, the active index of the listbox is still
                old.

                @param e: Tkinter event object.

                @return: None.
                """
                # Set new active index
                self.indexcur_set_by_event(e, notify=True)

                # Call the wrapped event handler
                handler(e)

            # Add the event handler wrapper to the listbox widget
            self._listbox.bind(event, handler_wrapper)

    def _on_single_click(self, event):
        """
        `<Button-1>` event handler that updates active index.

        @param event: Tkinter event object.

        @return: None.
        """
        # Updates active index
        self.indexcur_set_by_event(event, notify=True)

    def _on_double_click(self, event):
        """
        `<Double-Button-1>` event handler that updates active index.

        @param event: Tkinter event object.

        @return: None.
        """
        # Updates active index
        self.indexcur_set_by_event(event, notify=True)

    def _listbox_widget_update(
        self,
        keep_active,
    ):
        """
        Update listbox widget's items and selection.

        @param keep_active: Whether keep or clear active index.

        @return: None.
        """
        # Remove old items from listbox widget
        self._listbox.delete(0, END)

        # Insert new items into listbox widget.
        # For each ListboxVidget items.
        for index, item in enumerate(self.items()):
            # Get item text
            item_text = self._item_to_text(item)

            # Insert the item text into listbox widget
            self._listbox.insert(index, item_text)

            # Set the item's normal background color
            self._listbox.itemconfig(index, background=self._normal_bg)

            # Set the item's normal foreground color
            self._listbox.itemconfig(index, foreground=self._normal_fg)

            # Set the item's selected background color
            self._listbox.itemconfig(index, selectbackground=self._selected_bg)

            # Set the item's selected foreground color
            self._listbox.itemconfig(index, selectforeground=self._selected_fg)

        # If keep active index
        if keep_active:
            # Use old active index
            indexcur = self._indexcur

        # If not keep active index
        else:
            # Set active index to -1
            indexcur = self._indexcur = -1

        # Clear old selection
        self._listbox.selection_clear(0, END)

        # Set new selection.
        # `-1` works.
        self._listbox.selection_set(indexcur)

        # Set new active index.
        # `-1` works.
        self._listbox.activate(indexcur)

        # If new active index is valid
        if indexcur != -1:
            # Set active background color
            self._listbox.itemconfig(indexcur, background=self._active_bg)

            # Set active foreground color
            self._listbox.itemconfig(indexcur, foreground=self._active_fg)

            # Make the active item visible
            self._listbox.see(indexcur)
Exemplo n.º 27
0
class Ufd:
    """
        Universal File Dialog - "UFD"
        
        Unopinionated, minimalist, reusable, slightly configurable,
        general-purpose file-dialog.
    """
    def __init__(self,
                 title: str = "Universal File Dialog",
                 icon: str = "",
                 show_hidden: bool = False,
                 include_files: bool = True,
                 multiselect: bool = True,
                 select_dirs: bool = True,
                 select_files: bool = True,
                 unix_delimiter: bool = True,
                 stdout: bool = False):
        """
            Init kwargs as object attributes, save references to 
            Tk PhotoImages, & define the widgets + layout
        """

        if not isinstance(title, str):
            raise TypeError("Argument title must be type string.")

        self.title = title

        if icon:
            if not isinstance(icon, str):
                raise TypeError("Argument icon must be type string.")

            if not isfile(icon):
                raise FileNotFoundError(f"File not found: {icon}")

            self.icon = icon

        else:
            self.icon = ""

        if show_hidden:
            self.show_hidden = True
        else:
            self.show_hidden = False

        if include_files:
            self.include_files = True
        else:
            self.include_files = False

        if multiselect:
            self.multiselect = True
        else:
            self.multiselect = False

        if select_dirs:
            self.select_dirs = True
        else:
            self.select_dirs = False

        if select_files:
            self.select_files = True
        else:
            self.select_files = False

        if unix_delimiter:
            self.unix_delimiter = True
        else:
            self.unix_delimiter = False

        if stdout:
            self.stdout = True
        else:
            self.stdout = False

        # Tkinter:
        self.dialog = Tk()
        self.dialog.withdraw()
        self.dialog.title(self.title)
        self.dialog.minsize(width=300, height=200)
        self.dialog.geometry("500x300")
        self.dialog.update_idletasks()

        self.file_icon = PhotoImage(file=f"{dirname(__file__)}/file.gif",
                                    master=self.dialog).subsample(50)

        self.folder_icon = PhotoImage(file=f"{dirname(__file__)}/folder.gif",
                                      master=self.dialog).subsample(15)

        self.disk_icon = PhotoImage(file=f"{dirname(__file__)}/disk.gif",
                                    master=self.dialog).subsample(15)

        if self.icon:
            self.dialog.iconbitmap(self.icon)
        else:
            self.dialog.iconbitmap(f"{dirname(__file__)}/icon.ico")

        # Widgets:
        self.paneview = PanedWindow(
            self.dialog,
            sashwidth=7,
            bg="#cccccc",
            bd=0,
        )

        self.left_pane = PanedWindow(self.paneview)
        self.right_pane = PanedWindow(self.paneview)
        self.paneview.add(self.left_pane)
        self.paneview.add(self.right_pane)

        self.treeview_x_scrollbar = Scrollbar(self.left_pane,
                                              orient="horizontal")
        self.treeview_y_scrollbar = Scrollbar(self.left_pane,
                                              orient="vertical")
        self.list_box_x_scrollbar = Scrollbar(self.right_pane,
                                              orient="horizontal")
        self.list_box_y_scrollbar = Scrollbar(self.right_pane,
                                              orient="vertical")

        # tstyle = Style().configure(".", )

        self.treeview = Treeview(
            self.left_pane,
            xscrollcommand=self.treeview_x_scrollbar.set,
            yscrollcommand=self.treeview_y_scrollbar.set,
            show="tree",
            selectmode="browse",
            # style=tstyle
        )

        self.list_box = Listbox(self.right_pane,
                                xscrollcommand=self.list_box_x_scrollbar.set,
                                yscrollcommand=self.list_box_y_scrollbar.set,
                                width=34,
                                highlightthickness=0,
                                bd=2,
                                relief="ridge")

        if self.multiselect:
            self.list_box.config(selectmode="extended")
        else:
            self.list_box.config(selectmode="browse")

        self.cancel_button = Button(self.left_pane,
                                    text="Cancel",
                                    command=self.cancel)

        self.submit_button = Button(self.right_pane,
                                    text="Submit",
                                    command=self.submit)

        self.treeview_x_scrollbar.config(command=self.treeview.xview)
        self.treeview_y_scrollbar.config(command=self.treeview.yview)
        self.list_box_x_scrollbar.config(command=self.list_box.xview)
        self.list_box_y_scrollbar.config(command=self.list_box.yview)

        #Layout:
        self.dialog.rowconfigure(0, weight=1)
        self.dialog.columnconfigure(0, weight=1)

        self.left_pane.grid_rowconfigure(0, weight=1)
        self.left_pane.grid_columnconfigure(0, weight=1)
        self.right_pane.grid_rowconfigure(0, weight=1)
        self.right_pane.grid_columnconfigure(0, weight=1)

        self.paneview.paneconfigure(
            self.left_pane,
            minsize=100,
            #Start off w/ the sash centered in the GUI:
            width=(self.dialog.winfo_width() / 2) - ceil(
                (self.paneview.cget("sashwidth") * 1.5)),
        )
        self.paneview.paneconfigure(self.right_pane, minsize=100)

        self.paneview.grid(row=0, column=0, sticky="nsew")

        self.treeview.grid(row=0, column=0, sticky="nsew")
        self.treeview_y_scrollbar.grid(row=0, column=1, sticky="ns")
        self.treeview_x_scrollbar.grid(row=1,
                                       column=0,
                                       columnspan=2,
                                       sticky="ew")

        self.list_box.grid(row=0, column=0, sticky="nsew")
        self.list_box_y_scrollbar.grid(row=0, column=1, sticky="ns")
        self.list_box_x_scrollbar.grid(row=1,
                                       column=0,
                                       columnspan=2,
                                       sticky="ew")

        self.cancel_button.grid(row=2, column=0, sticky="w", padx=10, pady=10)
        self.submit_button.grid(row=2,
                                column=0,
                                columnspan=2,
                                sticky="e",
                                padx=10,
                                pady=10)

        #Bindings, Protocols, & Misc:
        self.dialog.bind("<Control-w>", self.cancel)
        self.treeview.bind("<<TreeviewSelect>>", self.treeview_select)
        self.treeview.bind("<Double-Button-1>", self.dialog_populate)
        self.treeview.bind("<Return>", self.dialog_populate)
        self.treeview.bind("<Right>", self.dialog_populate)
        self.list_box.bind("<<ListboxSelect>>", self.list_box_select)
        self.list_box.bind("<Return>", self.submit)
        self.dialog.protocol("WM_DELETE_WINDOW", self.cancel)

        self.dialog_selection = deque()
        self.selection_paths = deque()

        for disk in self.get_disks():
            self.treeview.insert(
                "",
                index="end",
                text=disk,
                image=self.disk_icon,
            )

        self.dialog.focus()

    def __call__(self):
        """
            Display dialog & return selection
        """

        (width_offset, height_offset) = self.get_offset(self.dialog)
        self.dialog.geometry(f"+{width_offset}+{height_offset}")
        self.dialog.update_idletasks()
        self.dialog.deiconify()

        self.dialog.wait_window()

        for i, path in enumerate(self.dialog_selection):
            if self.unix_delimiter:
                self.dialog_selection[i] = sub("\\\\", "/", path)
            else:
                self.dialog_selection[i] = sub("/", "\\\\", path)

        if self.stdout:
            [print(item) for item in self.dialog_selection]

        return list(self.dialog_selection)

    def __str__(self):
        """
            Return own address
        """

        return "Universal File Dialog"\
        f" @ {hex(id(self))}"

    def __repr__(self):
        """
            Return full string representation of constructor signature
        """

        return f"Ufd("\
        f"title=\"{self.title}\","\
        f" icon=\"{self.icon}\","\
        f" show_hidden={self.show_hidden},"\
        f" include_files={self.include_files},"\
        f" multiselect={self.multiselect},"\
        f" select_dirs={self.select_dirs},"\
        f" select_files={self.select_files},"\
        f" unix_delimiter={self.unix_delimiter})"\
        f" stdout={self.stdout})"\
        f" @ {hex(id(self))}"

    @staticmethod
    def get_offset(tk_window):
        """
            Returns an appropriate offset for a given tkinter toplevel,
            such that it always is created center screen on the primary display.
        """

        width_offset = int((tk_window.winfo_screenwidth() / 2) -
                           (tk_window.winfo_width() / 2))

        height_offset = int((tk_window.winfo_screenheight() / 2) -
                            (tk_window.winfo_height() / 2))

        return (width_offset, height_offset)

    @staticmethod
    def get_disks():
        """
            Returns all mounted disks (for Windows)

            >> ["A:", "B:", "C:"]
        """

        if system() != "Windows":
            raise OSError("For use with Windows platforms.")

        logicaldisks = run(["wmic", "logicaldisk", "get", "name"],
                           capture_output=True)

        return findall("[A-Z]:", str(logicaldisks.stdout))

    @staticmethod
    def list_dir(path, force=False):
        """
            Reads a directory with a shell call to dir.
            Truthiness of bool force determines whether 
            hidden items are returned or not. (For Windows)
        """

        path = sub("/", "\\\\", path)

        if force:
            dir_listing = run(["dir", path, "/b", "/a"],
                              shell=True,
                              capture_output=True)

        else:
            dir_listing = run(["dir", path, "/b"],
                              shell=True,
                              capture_output=True)

        output = dir_listing.stdout
        err = dir_listing.stderr

        if not output:
            return []

        if err:
            err = err.decode("utf-8")
            raise Exception(err)

        str_output = output.decode("utf-8")
        list_output = re_split("\r\n", str_output)

        return sorted([item for item in list_output if item])

    def climb(self, item):
        """
            Builds & returns a complete path to root directory,
            including the item name itself as the path tail.
            An extra delimiter is appeneded for the subsequent
            child node, which is normalized in dialog_populate()
        """

        item_text = self.treeview.item(item)["text"]
        parent = self.treeview.parent(item)
        path = ""
        parents = deque()

        while parent:
            parents.append(self.treeview.item(parent)["text"] + "/")
            parent = self.treeview.parent(parent)

        for parent in reversed(parents):
            path += parent

        path += item_text + "/"
        return path

    def dialog_populate(self, event=None):
        """
            Dynamically populates & updates the treeview, listbox,
            and keeps track of the full paths corresponding to each
            item in the listbox
        """
        if not self.treeview.focus():
            return

        self.treeview.column("#0", width=1000)

        existing_children = self.treeview.get_children(self.treeview.focus())
        [self.treeview.delete(child) for child in existing_children]

        self.list_box.delete(0, "end")
        self.selection_paths.clear()

        focus_item = self.treeview.focus()
        path = self.climb(focus_item)

        if self.show_hidden:
            children = self.list_dir(path, force=True)
        else:
            children = self.list_dir(path)

        for child in children:
            if isdir(path + child):

                self.treeview.insert(focus_item,
                                     index="end",
                                     text=child,
                                     image=self.folder_icon)

                if self.select_dirs:
                    self.list_box.insert("end", child)
                    self.selection_paths.append(path + child)

            elif isfile(path + child):

                if self.include_files:
                    self.treeview.insert(focus_item,
                                         index="end",
                                         text=child,
                                         image=self.file_icon)

                if self.select_files:
                    self.list_box.insert("end", child)
                    self.list_box.itemconfig("end", {"bg": "#EAEAEA"})
                    self.selection_paths.append(path + child)

        if isfile(normpath(path)):
            (head, tail) = path_split(normpath(path))
            head = sub("\\\\", "/", head)

            self.list_box.insert("end", tail)
            self.selection_paths.append(head + "/" + tail)
            self.list_box.itemconfig("end", {"bg": "#EAEAEA"})

    def list_box_select(self, event=None):
        """
            Dynamically refresh the dialog selection with
            what's selected in the listbox
            (Callback for <<ListboxSelect>>).
        """

        self.dialog_selection.clear()

        for i in self.list_box.curselection():
            self.dialog_selection.append(self.selection_paths[i])

    def treeview_select(self, event=None):
        """
            Dynamically refresh the dialog selection with
            what's selected in the treeview
            (Callback for <<TreeviewSelect>>).
        """

        for i in self.list_box.curselection():
            self.list_box.selection_clear(i)

        self.dialog_selection.clear()

        item = normpath(self.climb(self.treeview.focus()))
        self.dialog_selection.append(item)

    def submit(self, event=None):
        """
            Satisfies wait_window() in self.__call__() and validates selection

            (Callback for <Return>, <Button-1> on file_list, submit_button)
        """

        if self.select_dirs == False:
            for item in self.dialog_selection:
                if isdir(item):
                    messagebox.showwarning(
                        "Error - Invalid Selection",
                        "Unable to select directory. Please select a file(s).")
                    return

        if self.select_files == False:
            for item in self.dialog_selection:
                if isfile(item):
                    messagebox.showwarning(
                        "Error - Invalid Selection",
                        "Unable to select file. Please select a folder(s)")
                    return

        self.dialog.destroy()

    def cancel(self, event=None):
        """
            Satisfies wait_window() in self.__call__() 

            (Callback for <Button-1> on cancel_button)
            (Callback for protocol "WM_DELETE_WINDOW" on self.dialog)
        """

        self.dialog_selection.clear()
        self.dialog.destroy()
    def historyTab():
        # window that shows history of all chats.
        historyWindow = Toplevel(root)
        root.withdraw()
        historyWindow.title("{} - History".format(userEmailAddress))
        historyWindow.geometry("1000x800")
        historyWindow.config(bg="#ccffcc")
        historyWindow.resizable(height=False, width=False)

        historyList = Listbox(
            historyWindow,
            height=37,
            width=96,
            bg="#ccffcc",
            foreground="#446665",
            font=("Verdana", 12),
            borderwidth=5,
        )
        historyList.place(x=10, y=10)

        def returnList(text):
            responseList = []
            i = 0
            while i < len(text):
                if len(text) - i > 87:
                    responseList.append(text[i:i + 87] + '-')
                    i = i + 87
                else:
                    responseList.append(text[i:])
                    break
            return responseList

        scrollbary = Scrollbar(historyWindow, command=historyList.yview)
        historyList['yscrollcommand'] = scrollbary.set
        scrollbary.place(x=985, y=10, height=720)
        scrollbary.config(bg="#ccffcc")

        #scrollbarx = Scrollbar(historyWindow, command=historyList.xview, orient="horizontal")
        #historyList['xscrollcommand'] = scrollbarx.set
        #scrollbarx.place(x=10, y=725, width=980)
        #scrollbarx.config(bg="#ccffcc")

        mycursor = con.execute(""" select * from MsgStoreHistory """)
        histories = mycursor.fetchall()
        i = 1
        try:
            dateTime = str(histories[0][0])
            date = dateTime[:10]
            historyList.insert(i, date)
            historyList.itemconfig(i - 1, {'fg': 'red'})
            i += 1
            for chats in histories:
                chatsDateTime = str(chats[0])
                chatsDate = chatsDateTime[:10]
                chatsTime = chatsDateTime[11:]
                if chatsDate != date:
                    historyList.insert(i, " ")
                    i += 1
                    date = chatsDate
                    historyList.insert(i, date)
                    historyList.itemconfig(i - 1, {'fg': 'red'})
                    i += 1
                else:
                    pass
                if chats[1] == userEmailAddress:
                    textList = returnList(chats[2])
                    historyList.insert("end",
                                       chatsTime + " : You: " + textList[0])
                    historyList.itemconfig("end", {'fg': 'blue'})
                    for response in textList[1:]:
                        historyList.insert(
                            "end", "                            " + response)
                        historyList.itemconfig("end", {'fg': 'blue'})
                    i += 1
                elif chats[1] == "bot" + userEmailAddress:
                    textList = returnList(chats[2])
                    historyList.insert("end",
                                       chatsTime + " : Bot: " + textList[0])
                    historyList.itemconfig("end", {'fg': 'green'})
                    for response in textList[1:]:
                        historyList.insert(
                            "end",
                            "                                 " + response)
                        historyList.itemconfig("end", {'fg': 'green'})
                    i += 1
        except IndexError:
            pass

        # calls when user invokes clear button
        def clearButtonListener():
            answer = messagebox.askyesno("Clear", "Sure?")
            if answer == True:
                con.execute(
                    """ delete from MsgStoreHistory where sender in ("{}", "{}") """
                    .format(userEmailAddress, 'bot' + userEmailAddress))
                con.commit()
                historyList.delete(0, "end")
                messagebox.showinfo("Clear",
                                    "All the chat history has been deleted.")
            else:
                pass

        # loading and using clear button image
        clearButton = Button(historyWindow,
                             image=clear_button_image,
                             bg="#ccffcc",
                             borderwidth=0,
                             command=clearButtonListener)
        clearButton.place(x=8, y=740)

        # exports the chats to a file appended with current time. (Invokes when 'export chats history' invoke in menu bar of this particular window.)
        def exportChats():
            timestr = str(datetime.now())
            textFile = open(
                "Histories/{}_chatHistories_{}.txt".format(
                    userEmailAddress, '_'.join([
                        timestr[:4], timestr[5:7], timestr[8:10],
                        timestr[11:13], timestr[14:16], timestr[17:19]
                    ])), 'w')
            mycursor = con.execute(""" select * from MsgStoreHistory """)
            messages = mycursor.fetchall()
            for message in messages:
                if message[1] == userEmailAddress:
                    textFile.write(
                        str(message[0]) + " => You:" + message[2] + '\n')
                elif message[1] == 'bot' + userEmailAddress:
                    textFile.write(
                        str(message[0]) + " => Bot:" + message[2] + '\n')
            textFile.close()
            messagebox.showinfo(
                "Export",
                """ Chats has been exported to "{}_chatsHistory_{}.txt" file """
                .format(
                    userEmailAddress, '_'.join([
                        timestr[:4], timestr[5:7], timestr[8:10],
                        timestr[11:13], timestr[14:16], timestr[17:19]
                    ])))

        # calks when user exits from the history window.
        def exitWindow():
            root.deiconify()
            historyWindow.withdraw()

        # menu bar for history window
        menubar = Menu(historyWindow, bg="#ccffcc")
        options = Menu(menubar, tearoff=0, bg="#ccffcc")
        menubar.add_cascade(label="Options", menu=options)
        options.add_command(label="Export Chat History", command=exportChats)
        options.add_separator()
        options.add_command(label="Exit", command=exitWindow)
        historyWindow.config(menu=menubar)

        historyWindow.protocol("WM_DELETE_WINDOW", exitWindow)
Exemplo n.º 29
0
class CompilationScreen(TkPage):
    Name = 'Compilation'
    Font = lambda Size: ('Courier', Size) #font of the page

    def __init__(self, Parent, *args, **kwargs):
        super().__init__() #constructor of super class
        self.Songs = [Song for Song in DirList('Songs') if Song.endswith('.mid')] #mappable songs
        self.MappedSongs = [Song for Song in DirList('MappedSongs') if Song.endswith('.cmid')] #mapped and compiled song

        TopLabel = Label(self, text = 'Compile a Song', font= CompilationScreen.Font(24), bd = 10) #top label with a title for the page
        TopLabel.place(anchor= 'n', relx= 0.5, rely = 0.015, relwidth = 1, relheight=0.15) #placing the label

        self.ItemList = ListBox(self) #item list of the song
        for Index, Item in enumerate(self.Songs): #for loop for every compiled comiled song
            self.ItemList.insert(Index, Item) #indexing the song in the list
            self.ItemList.itemconfig(Index, {'bg' : '#C2C2C2'})
        self.ItemList.place(anchor= 'n', relx= 0.5, rely = 0.19, relwidth = 1, relheight = 0.46) #placing the item list

        self.ApproxValue = IntVar()
        self.ApproxValue.set(1)
        self.SingleTracks = IntVar()
        self.SingleTracks.set(0)

        self.Closest = Radio(self, text = 'Closest Approximation (A# = A, A- = A)', variable = self.ApproxValue, value = 1)
        self.Closest.place(anchor = 'nw', relx = 0.008, rely = 0.65, relheight = 0.07, relwidth = 0.6)
        self.Upper = Radio(self, text = 'Upper Approximation (A# = B, A- = A)', variable = self.ApproxValue, value = 0)
        self.Upper.place(anchor = 'nw', relx = 0.008, rely = 0.71, relheight = 0.07, relwidth = 0.6)
        self.Split = Check(self, text = 'Split MIDI into single tracks', variable = self.SingleTracks, onvalue = 1, offvalue = 0)
        self.Split.place(anchor = 'nw', relx = 0.008, rely = 0.77, relheight = 0.07, relwidth = 0.6)

        self.Compilation = Button\
        (
            self,
            text = 'Compile selected song',
            command = lambda : self.CompileSong()
        )
        self.Compilation.place(anchor = 'nw', relx = 0.615, rely = 0.66, relheight = 0.17, relwidth = 0.38)

        self.Back = Button\
        (
            self,
            text = 'Back to Home',
            command = lambda : self.TurnBack()
        )
        self.Back.place(anchor = 'nw', relx = 0.008, rely = 0.84, relheight = 0.07, relwidth = 0.988)

    def CompileSong(self):
        Song = str(self.ItemList.get('active'))
        Approximation = bool(self.ApproxValue.get())
        SplitMIDI = bool(self.SingleTracks.get())

        if Approximation:
            print('closest approximation')
            Compile(Song, True, False, SplitMIDI)
        else:
            print('upper approximation')
            Compile(Song, False, True, SplitMIDI)

    def TurnBack(self):
        GenshinLyrePlayer.Raise(Home.Name)

    def Refresh(self): #this function update the song list
        self.Songs = [Song for Song in DirList('Songs') if Song.endswith('.mid')] #check the folder for the songs
        self.ItemList.delete('0','end') #delete every item of the list
        for Index, Item in enumerate(self.Songs): #loop for every song in the folder
            self.ItemList.insert(Index, Item) #index the song in the item list
            self.ItemList.itemconfig(Index, {'bg' : '#C2C2C2'}) #background of the itemlist
Exemplo n.º 30
0
class MainAppController(Frame):
    """ Main Application for GUI """
    def __init__(self, parent):
        """ Initialize Main Application """
        Frame.__init__(self, parent)

        # create a style object
        style = Style()
        style.configure('D.TButton', foreground='red3')
        style.configure('R.TButton',
                        foreground='DodgerBlue4',
                        font=("TkTextFont", 9, 'bold'))
        style.configure('B.TButton',
                        foreground='FireBrick4',
                        font=("TkTextFont", 9, 'bold'))

        # Left frame, column 1
        left_frame = Frame(master=self)
        left_frame.grid(row=1, column=1, padx=30, pady=35, rowspan=3)

        # Middle frame (info text, column 2)
        middle_frame = Frame(master=self)
        middle_frame.grid(row=1, column=2, padx=30, pady=35, rowspan=3)

        # Right frame (statistics, column 3)
        right_frame = Frame(master=self)
        right_frame.grid(row=1, column=3, padx=30, pady=35, rowspan=2)

        # LEFT FRAME WIDGET
        Label(left_frame, text="Book ID",
              font=("TkTextFont", 11)).grid(row=1, column=1, columnspan=3)
        self._book_list = Listbox(left_frame,
                                  height=10,
                                  width=10,
                                  font=("TkTextFont", 11),
                                  bg='LightSalmon2')
        self._book_list.grid(row=2, column=1)
        self._book_list.configure(justify="center")

        # Call this on select
        self._book_list.bind("<<ListboxSelect>>", self._update_textbox)

        # MIDDLE FRAME WIDGET
        Label(middle_frame, text="Book Summary",
              font=("TkTextFont", 11)).grid(row=1, column=2, columnspan=7)
        self._info_text = Text(master=middle_frame,
                               height=10,
                               width=45,
                               font=("TkTextFont", 11),
                               bg='plum2')
        self._info_text.grid(row=2, column=2, columnspan=7)
        self._info_text.tag_configure("bold", font=("TkTextFont", 10, "bold"))

        # RIGHT FRAME WIDGET
        Label(right_frame, text="Book Statistics",
              font=("TkTextFont", 11)).grid(row=1, column=1, columnspan=3)
        self._book_stat = Text(master=right_frame,
                               height=10.5,
                               width=30,
                               font=("TkTextFont", 10),
                               bg='LightSalmon2')
        self._book_stat.grid(row=2, column=1, rowspan=3)
        self._book_stat.tag_configure("bold", font=("TkTextFont", 10, "bold"))

        # Drop Down menu to add a book
        self._add_var = StringVar(left_frame)
        choices = ['eBook', 'Textbook']
        OptionMenu(middle_frame, self._add_var, 'Select Type',
                   *choices).grid(row=3, column=2, pady=5, columnspan=4)

        # Drop Down menu to update a book
        self._update_var = StringVar(left_frame)
        choices = ['eBook', 'Textbook']
        OptionMenu(middle_frame, self._update_var, 'Select Type',
                   *choices).grid(row=3, column=3, pady=5, columnspan=7)

        # A couple buttons - using TTK
        Button(left_frame,
               text="Delete Book",
               width=13,
               command=self._delete_book,
               style='D.TButton').grid(row=3, column=1, pady=5)
        Button(left_frame, text="Quit", width=13,
               command=self._quit_callback).grid(row=4, column=1)
        Button(middle_frame, text="Add Book", width=13,
               command=self._add_book).grid(row=4, column=2, columnspan=4)
        Button(middle_frame,
               text="Update Book",
               width=13,
               command=self._update_book).grid(row=4, column=3, columnspan=7)
        Button(right_frame,
               text="Borrow Book",
               width=13,
               command=self._borrow_cb,
               style='B.TButton').grid(row=5, column=1, pady=5)
        Button(right_frame,
               text="Return Book",
               width=13,
               command=self._return_cb,
               style='R.TButton').grid(row=6, column=1)

        # Now update the list and Statistics
        self._update_book_list()

    def _update_textbox(self, *args):
        """ Updates the info text box on the right, based on the current ID selected """
        # This is a list, so we take just the first item (could be multi select...)
        try:
            selected_index = self._book_list.curselection()[0]
        except IndexError:
            return None
        book_id = self._book_list.get(selected_index)

        # Make a GET request
        r = requests.get(
            f"http://localhost:5000/library_manager/book/{book_id}")

        # Clear the text box
        self._info_text.delete(1.0, tk.END)

        # Check the request status code
        if r.status_code != 200:
            self._info_text.insert(tk.END, "Error running the request!")

        # For every item (key, value) in the JSON response, display them:
        for k, v in r.json().items():
            self._info_text.insert(tk.END, f"{k.capitalize()}\t\t", "bold")
            self._info_text.insert(tk.END, f"{v}\n")

        self._update_book_stat()

    def _update_book_list(self):
        """ Update the List of Books """
        r = requests.get("http://localhost:5000/library_manager/all")
        self._book_list.delete(0, tk.END)
        for s in r.json()["ebook"]:
            self._book_list.insert(tk.END, '{:^}'.format(s['book_id']))
            self._book_list.itemconfig(tk.END, {'fg': 'Blue4'})
            if s['is_borrowed']:
                self._book_list.itemconfig(tk.END, {'bg': 'khaki1'})

        for s in r.json()["textbook"]:
            self._book_list.insert(tk.END, '{:^}'.format(s['book_id']))
            self._book_list.itemconfig(tk.END, {'fg': 'Brown4'})
            if s['is_borrowed']:
                self._book_list.itemconfig(tk.END, {'bg': 'khaki1'})
        self._update_book_stat()

    def _update_book_stat(self):
        """ Update the List of Books """
        r = requests.get("http://localhost:5000/library_manager/all/stats")
        self._book_stat.delete(1.0, tk.END)
        for k, v in r.json().items():
            self._book_stat.insert(tk.END, f"{k}\t\t\t", "bold")
            self._book_stat.insert(tk.END, f"{v}\n")

    def _borrow_cb(self):
        """Borrow any book with the selected ID"""
        if not self._book_list.curselection():
            mb.showerror('Error : Item not selected', 'Please select a book.')
        else:
            selected_index = self._book_list.curselection()[0]
            book_id = self._book_list.get(selected_index)
            r = requests.get(
                f"http://127.0.0.1:5000/library_manager/book/{book_id}")
            if r.json()['is_borrowed']:
                mb.showerror('Error : Bad selection',
                             'Book is already borrowed.')
            else:
                response = requests.put(
                    f"http://127.0.0.1:5000/library_manager/{book_id}/borrow")
                if response.status_code == 200:
                    self._update_book_list()

    def _return_cb(self):
        """Return any book with the selected ID to library"""
        if not self._book_list.curselection():
            mb.showerror('Error : Item not selected', 'Please select a book.')
        else:
            selected_index = self._book_list.curselection()[0]
            book_id = self._book_list.get(selected_index)
            r = requests.get(
                f"http://127.0.0.1:5000/library_manager/book/{book_id}")
            if not r.json()['is_borrowed']:
                mb.showerror('Error : Bad selection',
                             'Book is already returned.')
            else:
                response = requests.put(
                    f"http://127.0.0.1:5000/library_manager/{book_id}/return_book"
                )
                if response.status_code == 200:
                    self._update_book_list()

    def _add_ebook(self):
        """ Add eBook Popup """
        self._popup_win = tk.Toplevel()
        self._popup = AddeBookPopup(self._popup_win, self._close_book_cb)

    def _add_textbook(self):
        """ Add Textbook Popup """
        self._popup_win = tk.Toplevel()
        self._popup = AddTextbookPopup(self._popup_win, self._close_book_cb)

    def _add_book(self):
        """Redirect add book based on the type"""
        if self._add_var.get() == 'eBook':
            self._add_ebook()
        elif self._add_var.get() == 'Textbook':
            self._add_textbook()
        else:
            mb.showerror('Error : Type not selected', 'Please select a type.')

    def _update_book(self):
        """Update eBook attributes"""
        if self._update_var.get() == 'eBook':
            self._update_ebook()
        elif self._update_var.get() == 'Textbook':
            self._update_textbook()
        else:
            mb.showerror('Error : Type not selected', 'Please select a type.')

    def _update_ebook(self):
        """Update ebook attributes in the 'Book' database"""
        if not self._book_list.curselection():
            mb.showerror('Error : Book not selected', 'Please select a book.')
        else:
            selected_index = self._book_list.curselection()[0]
            book_id = self._book_list.get(selected_index)
            r = requests.get(
                f"http://localhost:5000/library_manager/book/{book_id}")
            if r.json()['type'] != 'ebook':
                mb.showerror('Error : Invalid selection',
                             'Please select an ebook ID.')
            else:
                self._popup_win = tk.Toplevel()
                self._popup = UpdateeBookPopup(self._popup_win, book_id,
                                               self._close_book_cb)
        self._update_book_list()

    def _update_textbook(self):
        """Update textbook attributes in the 'Book' database"""
        if not self._book_list.curselection():
            mb.showerror('Error : Book not selected', 'Please select a book.')
        else:
            self._popup_win = tk.Toplevel()
            selected_index = self._book_list.curselection()[0]
            book_id = self._book_list.get(selected_index)
            r = requests.get(
                f"http://localhost:5000/library_manager/book/{book_id}")
            if r.json()['type'] != 'textbook':
                mb.showerror('Error : Invalid selection',
                             'Please select a textbook ID.')
            else:
                self._popup = UpdateTextbookPopup(self._popup_win, book_id,
                                                  self._close_book_cb)
        self._update_book_list()

    def _delete_book(self):
        """ Delete book Popup """
        self._popup_win = tk.Toplevel()
        self._popup = DeleteBook(self._popup_win, self._close_book_cb)

    def _close_book_cb(self):
        """ Close Popup """
        self._popup_win.destroy()
        self._update_book_list()

    def _quit_callback(self):
        """ Quit """
        self.quit()
Exemplo n.º 31
0
class Mainwindow(Frame):

    def __init__(self, height, width, server_host, users_list, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.height = height
        self.width = width
        self.server_host = server_host
        self.pack()
        self.createWidgets()
        self.setupFunctions()
        self.insert_text("Has entrado a la conversación!")
        self.add_connect(users_list[0])

    def createWidgets(self):
        self.chat_browser_scrollBar = Scrollbar(self.master)
        self.chat_browser_scrollBar.place(x=self.width-15, y=0, height=self.height*0.5)
        self.chat_browser = Text(self.master, yscrollcommand=self.chat_browser_scrollBar.set)
        self.chat_browser.place(x=0, y=0, width=self.width-15, height=self.height * 0.5)
        self.chat_browser.config(state=DISABLED)
        self.chat_browser_scrollBar.config(command=self.chat_browser.yview)
        self.text_writter = Text(self.master)
        self.text_writter.place(x=0, y=(self.height * 0.5) + 5, height=140)
        self.connected_list = Listbox(self.master)
        self.connected_list.place(x=self.width + 5, y=0, height=self.height * 0.5, width=self.width * 0.44)
        self.send_button = Button(self.master, text="Enviar", command=self.send_message)
        self.send_button.place(x=self.width * 1.22, y=self.height / 2 + 15, height=40, width=100)
        self.clear_button = Button(self.master, text="Borrar", command=self.clear_text)
        self.clear_button.place(x=self.width * 1.22, y=self.height / 2 + 80, height=40, width=100)


    def setupFunctions(self):
        self.text_writter.bind_all("<Return>", self.send_key_pressed)
        self.text_writter.bind_all("<BackSpace>", self.clear_key_pressed)

    def send_key_pressed(self, event):
        self.send_message()

    def clear_key_pressed(self, event):
        self.clear_text()

    def receive_message(self, host, message):
        text = host+":\n\t"+message
        self.insert_text(text)

    def insert_text(self, message):
        message += "\n"
        self.chat_browser.config(state=NORMAL)
        self.chat_browser.insert("end", message)
        self.chat_browser.config(state=DISABLED)
        self.chat_browser.see("end")

    def add_connect(self, item):
        color = "white"
        if self.connected_list.size() % 2 == 1:
            color = "#eaeae1"
        self.connected_list.insert("end", item)
        self.connected_list.itemconfig("end", bg=color)

    def delete_connect(self, item, list):
        list.remove(item)
        self.connected_list.delete(0, "end")
        for i in list:
            self.add_connect(i)

    def reset_connected_list(self, list):
        self.connected_list.delete(0, "end")
        for i in list:
            self.add_connect(i)

    def clear_text(self):
        self.text_writter.delete("1.0", "end")

    def send_message(self, text=None):
        message = text
        if not message:
            message = self.text_writter.get("1.0", "end")
            message = message.strip()
            self.text_writter.delete("1.0", "end")
        if not message:
            return

        print("Enviando mensaje:", message)
        start_new_thread(self.send_sock, (message,))

    def send_sock(self, message):
        message = message.encode(encoding="UTF-8")
        sock = socket(AF_INET, SOCK_STREAM)
        sock.connect((self.server_host))
        sock.send(message)
        sock.close()