def create_widget(self): self.widget = TK.Frame(self.parent.widget) # Add column headings label_canvas = self.widget left = self.h_gap top = self.v_gap for col in self.columns: place_label(canvas=label_canvas, txt=col['text'], left=left, top=top, width=col['width'], height=self.cellheight, bg=col['titlecolor'], anchor=col['anchor']) left += col['width'] + self.h_gap # Add data labels, and string variables for each label self.cells = [] top += self.cellheight + self.v_gap for i,row in enumerate(self.data): # row is a list if i >= self.view_rows: break cell_row = [] left=self.h_gap s = Separator(label_canvas) s.place(x=0, y=top -2, relwidth=1.0) for j, col in enumerate(self.columns): value = TK.StringVar() value.set('{}'.format(self.data[i][j])) place_label(canvas=label_canvas, txt="", left=left, top=top, width=col['width'], height=self.cellheight, bg=col['cellcolor'], anchor=col['labelanchor'], textvariable=value, name=':{}:{}'.format(i,j), clicked=self._dataclick) cell_row.append(value) left += col['width'] + self.h_gap self.cells.append(cell_row) top += self.cellheight + self.v_gap self.top_row = 0 # Add vertical scroll if needed if self.v_scroll: x = self.scroll_left y = self.scroll_top height = self.scroll_height z = len(self.data) - self.view_rows #vertical_scroll = TK.Scale(label_canvas.frame, orient=TK.VERTICAL, vertical_scroll = TK.Scale(label_canvas, orient=TK.VERTICAL, from_=0, to=z, command=self.vert_scroll, showvalue=0) vertical_scroll.place(x=x, y=y, width=23, height=height)
style.theme_create( "yummy", parent="clam", settings={ #style.theme_settings('default', { # start of theme extract 'Separator.separator': { "element create": ( 'image', "separator", #('invalid', "separator-v"), ## uncomment when using 2nd state { 'border': [3], 'sticky': 'nsew' }) } # 'border':[2], ## change from 3 to 2 # end of theme extract - don't forget to add comma at end when inserting }) fr1 = Frame(fr, height=250, width=250) fr1.grid(column=1, row=0, sticky='nsew', padx=5, pady=5) style.theme_use('yummy') # 'default' widg = Separator(fr1, orient="horizontal") widg.place(x=5, y=5, width=150) widg1 = Separator(fr1, orient="vertical") #widg1.state(['invalid']) ## uncomment when using 2nd state widg1.place(x=75, y=50, height=150, width=8) #, width=5 root.mainloop()
class MainWin: def __init__(self, parent): def Help(): t = Toplevel() t.title("Help") t.label = Label(t, text='This small program will read the currently playing song from VLC and copy it to a folder of your choosing.') t.label.pack() t.label2 = Label(t, text='Great for easily making playlists from large libraries!') t.label2.pack() t.label3 = Label(t, text='') t.label3.pack() t.label4 = Label(t, text='') t.label4.pack() t.label5 = Label(t, text='Before you can use this program you need to make sure you have a few settings set correctly in VLC.') t.label5.pack() t.label6 = Label(t, text='Make sure you pick "All" for "Show Settings" in the bottom left of your Preferences') t.label6.pack() t.label7 = Label(t, text='First check the "Web" box at Tools -> Preferences -> Interface -> Main interfaces') t.label7.pack() t.label8 = Label(t, text='Next set your password at Tools -> Preferences -> Interface -> Main interfaces -> Lua -> Lua HTTP') t.label8.pack() t.label9 = Label(t, text='Finally, go to Tools -> Preferences -> Input / Codecs and scroll down to Network Settings and set your "HTTP Server Port"') t.label9.pack() t.label10 = Label(t, text='Save your settings and restart VLC and you should be good to go!') t.label10.pack() def Browse(root): root.withdraw() self.dirname = tkinter.filedialog.askdirectory(parent=root, initialdir="/", title='Choose a directory to copy to') return self.dirname def CheckPort(host, port): """Warns user if port is not open.""" with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock: if sock.connect_ex((host, port)) != 0: tkinter.messagebox.showinfo('Error', 'Either VLC or the Port is not open!') self.startConnection.set(False) return False else: return True def ReadSettings(): Config = configparser.ConfigParser() if isfile('settings.ini') is True: Config.read('settings.ini') self.pswrd = Config.get('Settings', 'vlc password') self.port = Config.get('Settings', 'vlc http port') self.renameMethod = Config.get('Settings', 'renaming method') self.dirname = Config.get('Settings', 'new directory') self.overwriteAlways.set(Config.getboolean('Settings', 'overwrite always')) self.copyhotkey = Config.get('Settings', 'copy hotkey') Config.remove_section('Settings') return self.pswrd, self.port, self.renameMethod, self.dirname, self.overwriteAlways, self.copyhotkey def SaveSettings(pswrd, port, renameMethod, dirname, overwriteAlways, copyhotkey): Config = configparser.ConfigParser() cfgfile = open("settings.temp.ini", 'w+') Config.add_section('Settings') Config.set('Settings', 'vlc password', self.pswrd) Config.set('Settings', 'vlc http port', self.port) Config.set('Settings', 'renaming method', self.renameMethod) Config.set('Settings', 'new directory', self.dirname) Config.set('Settings', 'activate hotkey', str(self.activateHotkey.get())) Config.set('Settings', 'overwrite always', str(self.overwriteAlways.get())) Config.set('Settings', 'copy hotkey', self.copyhotkey) Config.write(cfgfile) time.sleep(.1) if isfile('settings.ini'): os.remove('settings.ini') cfgfile.close() os.rename('settings.temp.ini', 'settings.ini') def SetServerPass(): self.pswrd = self.PassEntry.get() return self.pswrd def SetServerPort(): if is_number(self.PortEntry.get()) is True: self.port = self.PortEntry.get() return self.port else: tkinter.messagebox.showinfo('Error', 'Only numbers allowed!') def SetRenameMethod(): if is_number(self.SetRenameEntry.get()) is False or int(self.SetRenameEntry.get()) > 6 or int(self.SetRenameEntry.get()) < 1: tkinter.messagebox.showinfo('Error', 'Only numbers 1-6 allowed!') else: self.renameMethod = self.SetRenameEntry.get() return self.renameMethod def SetHotkey(): hotkey = str(keyboard.read_key()) end = hotkey.rfind(' down') self.copyhotkey = hotkey[14:end] t = Toplevel() t.title("New Hotkey") t.label = Label(t, text='You chose: ' + self.copyhotkey) t.label.pack() return self.copyhotkey def CheckSettings(): if is_number(self.renameMethod) is True and int(self.renameMethod) > 0 and int(self.renameMethod) < 7: if is_number(self.port) is True: if self.pswrd != '': if self.dirname != '': return True else: return False else: return False else: return False else: return False def CheckVLC(): check = rwm.OpenProcess('vlc.exe') if check is not None: return 'Opened!' else: self.startConnection.set(False) return 'Not Open' def RenameMethods(): t = Toplevel() t.title("Rename Methods") t.label = Label(t, text='Here are your options for renaming!') t.label.pack() t.label2 = Label(t, text='1. Artist - Title') t.label2.pack() t.label3 = Label(t, text='2. Album - Title') t.label3.pack() t.label4 = Label(t, text='3. Artist - Album - Title') t.label4.pack() t.label5 = Label(t, text='4. Album - Artist - Title') t.label5.pack() t.label6 = Label(t, text='5. Title') t.label6.pack() t.label7 = Label(t, text='6. Don\'t Rename') t.label7.pack() def CurrentSong(): """When called, grabs info from VLC to rename the new file.""" status = vlcxml('status') if status is not None: startTitle = status.find("<info name='title'>") startArtist = status.find("<info name='artist'>") startAlbum = status.find("<info name='album'>") startStatus = status.find("<state>") fromstartTitle = status[startTitle:] fromstartArtist = status[startArtist:] fromstartAlbum = status[startAlbum:] fromstartStatus = status[startStatus:] endTitle = fromstartTitle.find("</info>") endArtist = fromstartArtist.find("</info>") endAlbum = fromstartAlbum.find("</info>") endStatus = fromstartStatus.find("</state>") title = fixName(fromstartTitle[19:endTitle]) artist = fixName(fromstartArtist[20:endArtist]) album = fixName(fromstartAlbum[19:endAlbum]) status = fixName(fromstartStatus[7:endStatus]) self.currentstatus = (status[0].upper() + status[1:]) if (artist + " - " + album + ' - ' + title) == " - - ": self.currentsong = 'No info available' self.currentartist = 'No info available' self.currentalbum = 'No info available' self.currenttitle = 'No info available' else: self.currentsong = (artist + " - " + album + ' - ' + title) self.currentartist = artist self.currentalbum = album self.currenttitle = title else: return None def vlcxml(page): if self.startConnection.get() is True: """Grabs the xml needed from VLC's HTTP server.""" s = requests.Session() s.auth = ('', self.pswrd) # Username is blank, just provide the password try: r = s.get('http://localhost:' + self.port + '/requests/' + str(page) + '.xml', verify=False) return r.text except requests.exceptions.RequestException as e: self.startConnection.set(False) tkinter.messagebox.showinfo('Error', 'Something went wrong! Check your settings and make sure VLC is open! \n\n' + str(e)) return None else: return None def is_number(num): """Given string 'num', returns true if 'num' is numeric.""" try: int(num) return True except ValueError: return False def fixName(t): """Given string 't', returns a filtered version.""" while t != (t.replace("&", "&").replace("<", "<").replace(">", ">") .replace("'", "'").replace('"', '"')): t = (t.replace("&", "&").replace("<", "<").replace(">", ">") .replace("'", "'").replace('"', '"')) return t def copyFile(): if CheckSettings() is True and CheckPort('127.0.0.1', int(self.port)) is True: """When called, grabs info from VLC to copy file to new path.""" x1 = vlcxml('status') start = x1.find('<currentplid>') end = x1.find('</currentplid>') plid = x1[start + 13:end] if plid is not None: x2 = vlcxml('playlist') start2 = x2.find('id="' + plid + '" duration=') fromStart = x2[start2:] start3 = fromStart.find('uri=') end2 = fromStart.find('/>') start3 = fromStart.find('uri=') end2 = fromStart.find('/>') filePath = fromStart[start3 + 13:end2 - 19] bugstart = x2.find(filePath) # Getting around VLC bug block bug1 = x2[bugstart:] bugend = bug1.find('/>') bugFixin = x2[:(bugstart + bugend)] bugg = bugFixin.count('vlc://nop') if bugg > 0: plid = str(int(plid) + bugg) start2 = x2.find('id="' + plid + '" duration=') fromStart = x2[start2:] start3 = fromStart.find('uri=') end2 = fromStart.find('/>') filePath = fromStart[start3 + 13:end2 - 1] # Bug block end convertURL = unquote(filePath) fileNameStart = convertURL.rfind('/') fileName = convertURL[fileNameStart:] newFile = (self.dirname + fileName) extensionStart = fileName.rfind('.') extension = fileName[extensionStart:] self.localtime = time.strftime("%H:%M:%S", time.localtime()) time.sleep(.1) try: if isfile(newFile) is True: if self.overwriteAlways.get() is True: os.remove(newFile) renameResponse = reName() if renameResponse is not None: if isfile(self.dirname + '/' + renameResponse + extension) is True: if self.overwriteAlways.get() is True: os.remove(self.dirname + '/' + renameResponse + extension) copy2(convertURL, self.dirname) os.rename(newFile, (self.dirname + '/' + renameResponse + extension)) self.ProgStatusVarLabel.config(text='Successful Overwrite at ' + self.localtime) else: self.ProgStatusVarLabel.config(text='File Already Exists! ' + self.localtime) else: copy2(convertURL, self.dirname) os.rename(newFile, (self.dirname + '/' + renameResponse + extension)) self.ProgStatusVarLabel.config(text='Successful Overwrite at ' + self.localtime) else: copy2(convertURL, self.dirname) self.ProgStatusVarLabel.config(text='Successful Copy at ' + self.localtime) else: self.ProgStatusVarLabel.config(text='File Already Exists! ' + self.localtime) else: renameResponse = reName() if renameResponse is not None: if isfile(self.dirname + '/' + renameResponse + extension) is True: if self.overwriteAlways.get() is True: os.remove(self.dirname + '/' + renameResponse + extension) copy2(convertURL, self.dirname) os.rename(newFile, (self.dirname + '/' + renameResponse + extension)) self.ProgStatusVarLabel.config(text='Successful Overwrite at ' + self.localtime) else: self.ProgStatusVarLabel.config(text='File Already Exists! ' + self.localtime) else: copy2(convertURL, self.dirname) os.rename(newFile, (self.dirname + '/' + renameResponse + extension)) self.ProgStatusVarLabel.config(text='Successful Copy at ' + self.localtime) else: copy2(convertURL, self.dirname) self.ProgStatusVarLabel.config(text='Successful Copy at ' + self.localtime) except PermissionError: self.ProgStatusVarLabel.config(text="File in use! Can't Delete " + self.localtime) elif CheckSettings() is False: tkinter.messagebox.showinfo('Error', 'Settings not correct, check your settings!') self.startConnection.set(False) def reName(): """When called, grabs info from VLC to rename the new file.""" status = vlcxml('status') startTitle = status.find("<info name='title'>") startArtist = status.find("<info name='artist'>") startAlbum = status.find("<info name='album'>") fromstartTitle = status[startTitle:] fromstartArtist = status[startArtist:] fromstartAlbum = status[startAlbum:] endTitle = fromstartTitle.find("</info>") endArtist = fromstartArtist.find("</info>") endAlbum = fromstartAlbum.find("</info>") title = fixName(fromstartTitle[19:endTitle]) artist = fixName(fromstartArtist[20:endArtist]) album = fixName(fromstartAlbum[19:endAlbum]) if int(self.renameMethod) > 0 and int(self.renameMethod) < 7: if self.renameMethod == "1": return str(artist + ' - ' + title) elif self.renameMethod == "2": return str(album + ' - ' + title) elif self.renameMethod == "3": return str(artist + ' - ' + album + ' - ' + title) elif self.renameMethod == "4": return str(album + ' - ' + artist + ' - ' + title) elif self.renameMethod == "5": return str(title) elif self.renameMethod == "6": return None def HotKeyBind(): if self.activateHotkey.get() is True: keyboard.add_hotkey(self.copyhotkey, copyFile) else: keyboard.clear_all_hotkeys() # Variables self.pswrd = '' self.port = '' self.renameMethod = '6' self.dirname = '' self.activateHotkey = BooleanVar() self.overwriteAlways = BooleanVar() self.startConnection = BooleanVar() self.copyhotkey = '' ReadSettings() self.currentsong = 'Nothing Playing!' self.currentartist = 'Nothing Playing!' self.currentalbum = 'Nothing Playing!' self.currenttitle = 'Nothing Playing!' self.currentstatus = 'Not Open' self.photo = PhotoImage(file='vlc banner.png') self.photo_label = Label(image=self.photo) self.photo_label.place(x=0, y=0) self.photo_label.image = self.photo self.seperator = Separator(parent, orient="horizontal") self.seperator.place(relwidth=1.0, y=131) Style().configure(self.seperator, background='#000') self.PassLabel = Label(parent, text='Vlc Server Password:'******'Times', 12), fg='black') self.PassLabel.place(x=5, y=145) self.PortLabel = Label(parent, text='Vlc Server Port:', font=('Times', 12), fg='black') self.PortLabel.place(x=40, y=195) self.RenMethLabel = Label(parent, text='Rename Method:', font=('Times', 12), fg='black') self.RenMethLabel.place(x=30, y=245) self.DirLabel = Label(parent, text='New Directory:', font=('Times', 12), fg='black') self.DirLabel.place(x=8, y=280) self.VLCStatusLabel = Label(parent, text='VLC Status:', font=('Times', 12), fg='black') self.VLCStatusLabel.place(x=27, y=305) self.ProgStatusLabel = Label(parent, text='Last Action:', font=('Times', 12), fg='black') self.ProgStatusLabel.place(x=27, y=330) self.CurrentSongLabel = Label(parent, text=('Current Song'), font=('Times', 12), fg='black') self.CurrentSongLabel.place(x=50, y=360) f = font.Font(self.CurrentSongLabel, self.CurrentSongLabel.cget("font")) f.configure(underline=True) self.CurrentSongLabel.configure(font=f) self.CurrentArtistLabel = Label(parent, text='Artist:', font=('Times', 12), fg='black') self.CurrentArtistLabel.place(x=17, y=385) self.CurrentAlbumLabel = Label(parent, text='Album:', font=('Times', 12), fg='black') self.CurrentAlbumLabel.place(x=10, y=410) self.CurrentTitleLabel = Label(parent, text='Title:', font=('Times', 12), fg='black') self.CurrentTitleLabel.place(x=24, y=435) self.PassVarLabel = Label(parent, text=self.pswrd, font=('Times', 12), fg='black') self.PassVarLabel.place(x=140, y=145) self.PortVarLabel = Label(parent, text=self.port, font=('Times', 12), fg='black') self.PortVarLabel.place(x=140, y=195) self.RenMethVarLabel = Label(parent, text=self.renameMethod, font=('Times', 12), fg='black') self.RenMethVarLabel.place(x=140, y=245) self.DirVarLabel = Label(parent, text=self.dirname, font=('Times', 12), fg='black') self.DirVarLabel.place(x=105, y=280) self.VLCStatusVarLabel = Label(parent, text='Not Open', font=('Times', 12), fg='black') self.VLCStatusVarLabel.place(x=105, y=305) self.ProgStatusVarLabel = Label(parent, text='Nothing yet!', font=('Times', 12), fg='black') self.ProgStatusVarLabel.place(x=105, y=330) self.CurrentArtistVarLabel = Label(parent, text=self.currentartist, font=('Times', 12), fg='black') self.CurrentArtistVarLabel.place(x=60, y=385) self.CurrentAlbumVarLabel = Label(parent, text=self.currentalbum, font=('Times', 12), fg='black') self.CurrentAlbumVarLabel.place(x=60, y=410) self.CurrentTitleVarLabel = Label(parent, text=self.currenttitle, font=('Times', 12), fg='black') self.CurrentTitleVarLabel.place(x=60, y=435) self.PassEntry = Entry(parent) self.PassEntry.place(w=120, h=35, x=240, y=140) self.PortEntry = Entry(parent) self.PortEntry.place(w=120, h=35, x=240, y=190) self.SetRenameEntry = Entry(parent) self.SetRenameEntry.place(w=120, h=35, x=240, y=240) def Refresh(): CurrentSong() self.PassVarLabel.config(text=self.pswrd) self.PortVarLabel.config(text=self.port) self.RenMethVarLabel.config(text=self.renameMethod) self.DirVarLabel.config(text=self.dirname) if self.startConnection.get() is False: self.CurrentArtistVarLabel.config(text='Start Connection to get info!') self.CurrentAlbumVarLabel.config(text='Start Connection to get info!') self.CurrentTitleVarLabel.config(text='Start Connection to get info!') self.VLCStatusVarLabel.config(text=CheckVLC()) else: self.CurrentArtistVarLabel.config(text=self.currentartist) self.CurrentAlbumVarLabel.config(text=self.currentalbum) self.CurrentTitleVarLabel.config(text=self.currenttitle) self.VLCStatusVarLabel.config(text=self.currentstatus) parent.after(500, Refresh) self.PassButton = Button(parent, text='Set', command=SetServerPass, font=('Times', 10)) self.PassButton.place(w=120, h=35, x=380, y=140) self.PortButton = Button(parent, text='Set', command=SetServerPort, font=('Times', 10)) self.PortButton.place(w=120, h=35, x=380, y=190) self.SetRenameButton = Button(parent, text='Set', command=SetRenameMethod, font=('Times', 10)) self.SetRenameButton.place(w=120, h=35, x=380, y=240) self.BrowseButton = Button(parent, text='Browse', command=lambda: Browse(Tk()), font=('Times', 10)) self.BrowseButton.place(w=120, h=35, x=570, y=290) self.SetHotkeyButton = Button(parent, text='Set Hotkey', command=SetHotkey, font=('Times', 10)) self.SetHotkeyButton.place(w=120, h=35, x=570, y=340) self.CopyButton = Button(parent, text='Copy File', command=copyFile, font=('Times', 10)) self.CopyButton.place(w=120, h=35, x=570, y=425) self.HelpButton = Button(parent, text='Setup', command=Help, font=('Times', 10)) self.HelpButton.place(w=120, h=35, x=570, y=140) self.HelpButton = Button(parent, text='Save Settings', command=lambda: SaveSettings(self.pswrd, self.port, self.renameMethod, self.dirname, self.overwriteAlways, self.copyhotkey), font=('Times', 10)) self.HelpButton.place(w=120, h=35, x=570, y=190) self.RenameMethodsButton = Button(parent, text='Renaming Methods', command=RenameMethods, font=('Times', 10)) self.RenameMethodsButton.place(w=120, h=35, x=570, y=240) self.ActivHotkeyCheckbox = Checkbutton(parent, text='Activate Hotkey', variable=self.activateHotkey, command=HotKeyBind, font=('Times', 10)) self.ActivHotkeyCheckbox.place(x=420, y=310) self.OvrAlwCheckbox = Checkbutton(parent, text='Overwrite New Files', variable=self.overwriteAlways, font=('Times', 10)) self.OvrAlwCheckbox.place(x=420, y=330) self.StartConCheckbox = Checkbutton(parent, text='Start Connection', variable=self.startConnection, font=('Times', 10)) self.StartConCheckbox.place(x=420, y=350) Refresh()
def initialize_settings_ui(self): # Initializes resamples field resamples_label = Label(self, text="Resamples (affects recognition accuracy)") resamples_label.place(y=12.5, x=12.5) resamples_text = tk.StringVar() resamples_text.set(self.settings["resamples"]) resamples_spin = Spinbox(self, from_=1, to=10, textvariable=resamples_text) resamples_spin.config(command=partial(self.save_settings, "resamples", lambda: int(resamples_text.get()))) resamples_spin.place(y=37.5, x=12.5) separator1 = Separator(self, orient='horizontal') separator1.place(y=62.5, x=12.5, width=375, height=1) # Initializes tolerance field tolerance_label = Label(self, text="Face matching tolerance (lower is more strict)") tolerance_label.place(y=68.75, x=12.5) tolerance_text = tk.StringVar() tolerance_text.set(self.settings["tolerance"]) tolerance_spin = Spinbox(self, from_=0, to=1, increment=0.1, textvariable=tolerance_text) tolerance_spin.config(command=partial(self.save_settings, "tolerance", lambda: float(tolerance_text.get()))) tolerance_spin.place(y=93.75, x=12.5) separator2 = Separator(self, orient='horizontal') separator2.place(y=118.75, x=12.5, width=375, height=1) # Initializes track period field track_period_label = Label(self, text="Track period (the number of frames between each recognition)") track_period_label.place(y=125, x=12.5) track_period_text = tk.StringVar() track_period_text.set(self.settings["track_period"]) track_period_spin = Spinbox(self, from_=1, to=30, textvariable=track_period_text) track_period_spin.config(command=partial(self.save_settings, "track_period", lambda: int(track_period_text.get()))) track_period_spin.place(y=150, x=12.5) separator3 = Separator(self, orient='horizontal') separator3.place(y=175, x=12.5, width=375, height=1) # Initializes blur method field blur_method_label = Label(self, text="Blur method") blur_method_label.place(y=181.25, x=12.5) blur_method_text = tk.StringVar() blur_method_text.set(self.settings["blur_method"]) blur_method_menu = Combobox(self, textvariable=blur_method_text, values=("pixelate", "blur", "blacken")) blur_method_text.trace('w', partial(self.save_settings, "blur_method", lambda: blur_method_text.get())) blur_method_menu.place(y=206.25, x=12.5) separator4 = Separator(self, orient='horizontal') separator4.place(y=231.25, x=12.5, width=375, height=1) # Initializes blur intensity field blur_intensity_label = Label(self, text="Blur intensity (filter size)") blur_intensity_label.place(y=237.5, x=12.5) blur_intensity_text = tk.StringVar() blur_intensity_text.set(self.settings["blur_intensity"]) blur_intensity_spin = Spinbox(self, from_=1, to=30, textvariable=blur_intensity_text) blur_intensity_spin.config(command=partial(self.save_settings, "blur_intensity", lambda: int(blur_intensity_text.get()))) blur_intensity_spin.place(y=262.5, x=12.5) separator5 = Separator(self, orient='horizontal') separator5.place(y=287.5, x=12.5, width=375, height=1) # Initializes display output field display_output_flag = tk.IntVar() display_output_flag.set(self.settings["display_output"]) display_output_checkbox = tk.Checkbutton(self, text='Display output', variable=display_output_flag, onvalue=1, offvalue=0) display_output_checkbox.config(command=partial(self.save_settings, "display_output", lambda: display_output_flag.get())) display_output_checkbox.place(y=293.75, x=12.5)
class Vista(Frame): # Inicializa el controlador y algunas variables globales # Params: # master: instancia de Window # modelo: Modelo def __init__(self, master, modelo): Frame.__init__(self, master) self.pack() self.master = master self.modelo = modelo self.controlador = Controlador(self.modelo, self) self.col1 = 'khaki1' self.col2 = 'snow' self.font = 'Helvetica' self.init_components() return #Inicializa los componentes de la Vista y los coloca def init_components(self): self.label_model = Label(self.master, text='Modelo', font=(self.font, 14), relief=GROOVE, bg=self.col2) self.label_data = Label(self.master, text='Datos', font=(self.font, 14), relief=GROOVE, bg=self.col2) self.label_pred = Label(self.master, text='Predicción', font=(self.font, 14), relief=GROOVE, bg=self.col2) self.label_res = Label(self.master, text='Resultados', font=(self.font, 14), relief=GROOVE, bg=self.col2) self.variable = StringVar() self.variable.set('Modelo 1') self.variable.trace("w", self.change_model) self.model_selector = OptionMenu(self.master, self.variable, *list(self.modelo.modelos.keys())) self.frame = Frame(self.master) self.alg_label = Label(self.frame, text='Algoritmo', font=(self.font, 8, 'bold'), bg=self.col2, relief='raised', width=20) self.seas_label = Label(self.frame, text='Temporadas', font=(self.font, 8, 'bold'), bg=self.col2, relief='raised', width=20) self.columns_label = Label(self.frame, text='Selección columnas', font=(self.font, 8, 'bold'), bg=self.col2, relief='raised', width=20) self.pca_label = Label(self.frame, text='PCA', font=(self.font, 8, 'bold'), bg=self.col2, relief='raised', width=20) self.params_label = Label(self.frame, text='Parámetros', bg=self.col2, font=(self.font, 8, 'bold'), relief='raised', width=20) self.alg_value = Label(self.frame, text='', font=(self.font, 8), bg=self.col2, relief='raised', width=30) self.seas_value = Label(self.frame, text='', font=(self.font, 8), bg=self.col2, relief='raised', width=30) self.columns_value = Label(self.frame, text='', font=(self.font, 8), bg=self.col2, relief='raised', width=30) self.pca_value = Label(self.frame, text='', font=(self.font, 8), bg=self.col2, relief='raised', width=30) self.params_value = Label(self.frame, text='', font=(self.font, 8), bg=self.col2, relief='raised', width=30) self.load_model_but = Button(self.master, text='Cargar modelo', state='disabled', command=self.load_model, bg=self.col2) self.train_model_but = Button(self.master, text='Entrenar modelo', state='disabled', command=self.train_model, bg=self.col2) self.load_data_but = Button(self.master, text='Cargar datos', command=self.load_data, bg=self.col2) self.ref_but = Button(self.master, text='Actualizar datos', command=self.refresh, bg=self.col2) self.home_label = Label(self.master, text='Equipo local', bg=self.col1) self.away_label = Label(self.master, text='Equipo visitante', bg=self.col1) self.home = StringVar() self.home.set(self.modelo.teams[0]) self.homeOptionMenu = OptionMenu(self.master, self.home, *list(self.modelo.teams)) self.homeOptionMenu.config(state='disabled') self.away = StringVar() self.away.set(self.modelo.teams[0]) self.awayOptionMenu = OptionMenu(self.master, self.away, *list(self.modelo.teams)) self.awayOptionMenu.config(state='disabled') self.calendar = Calendar(self.master, state='disabled') self.pred_but = Button(self.master, text='Hallar predicciones', state='disabled', command=self.exec_prediction, bg=self.col2) self.result = Label(self.master, text='', bg=self.col1, font=(self.font, 10, 'bold')) self.pred = Label(self.master, text='', bg=self.col1, font=(self.font, 10, 'bold')) self.team_win = Label(self.master, text='', bg=self.col1, font=(self.font, 10, 'bold')) self.sep1 = Separator(self.master, orient=HORIZONTAL) self.sep2 = Separator(self.master, orient=HORIZONTAL) self.sep3 = Separator(self.master, orient=VERTICAL) self.label_error = Label(self.master, text='', font=('device', 10), fg='red', bg=self.col1) ### PACKING & PLACING self.label_model.pack() self.label_model.place(relx=0.05, rely=0.05, anchor=W) self.label_data.pack() self.label_data.place(relx=0.05, rely=0.4, anchor=W) self.label_pred.pack() self.label_pred.place(relx=0.05, rely=0.6, anchor=W) self.model_selector.pack() self.model_selector.place(relx=0.15, rely=0.15, anchor=CENTER) self.frame.pack() self.frame.place(relx=0.25, rely=0.05) self.alg_label.grid(row=0, rowspan=1, column=0, columnspan=1) self.seas_label.grid(row=1, rowspan=1, column=0, columnspan=1) self.columns_label.grid(row=2, rowspan=1, column=0, columnspan=1) self.pca_label.grid(row=3, rowspan=1, column=0, columnspan=1) self.params_label.grid(row=4, rowspan=1, column=0, columnspan=1, sticky=N + E + S + W) self.alg_value.grid(row=0, rowspan=1, column=1, columnspan=1) self.seas_value.grid(row=1, rowspan=1, column=1, columnspan=1) self.columns_value.grid(row=2, rowspan=1, column=1, columnspan=1) self.pca_value.grid(row=3, rowspan=1, column=1, columnspan=1) self.params_value.grid(row=4, rowspan=1, column=1, columnspan=1) self.change_model() self.load_model_but.pack() self.load_model_but.place(relx=0.1, rely=0.48, anchor=CENTER) self.train_model_but.pack() self.train_model_but.place(relx=0.24, rely=0.48, anchor=CENTER) self.load_data_but.pack() self.load_data_but.place(relx=0.38, rely=0.48, anchor=CENTER) self.ref_but.pack() self.ref_but.place(relx=0.52, rely=0.48, anchor=CENTER) self.home_label.pack() self.home_label.place(relx=0.1, rely=0.7, anchor=CENTER) self.away_label.pack() self.away_label.place(relx=0.25, rely=0.7, anchor=CENTER) self.homeOptionMenu.pack() self.homeOptionMenu.place(relx=0.1, rely=0.75, anchor=CENTER) self.awayOptionMenu.pack() self.awayOptionMenu.place(relx=0.25, rely=0.75, anchor=CENTER) self.calendar.pack() self.calendar.place(relx=0.45, rely=0.75, anchor=CENTER) self.pred_but.pack() self.pred_but.place(relx=0.17, rely=0.82, anchor=CENTER) self.label_res.pack() self.label_res.place(relx=0.7, rely=0.05, anchor=CENTER) self.result.pack() self.result.place(relx=0.8, rely=0.15, anchor=CENTER) self.pred.pack() self.pred.place(relx=0.8, rely=0.85, anchor=CENTER) self.team_win.pack() self.team_win.place(relx=0.8, rely=0.89, anchor=CENTER) self.sep1.place(relx=0.05, rely=0.33, relwidth=0.55) self.sep2.place(relx=0.05, rely=0.53, relwidth=0.55) self.sep3.place(relx=0.61, rely=0.05, relheight=0.9) self.label_error.place(relx=0.8, rely=0.93, anchor=CENTER) # Evento de cambiar el modelo que se esta seleccionando def change_model(self, *args): self.controlador.evento_change_model() if self.modelo.model_read is not None: self.alg_value['text'] = self.modelo.algorithms[ self.modelo.model_read.alg] if self.modelo.model_read.seasons == '2015': seas = 'Desde 2014/2015' elif self.modelo.model_read.seasons == '2005': seas = 'Desde 2004/2005' else: seas = 'Desde 2000/2001' self.seas_value['text'] = seas self.columns_value['text'] = self.modelo.model_read.col self.pca_value[ 'text'] = 'Sí' if self.modelo.model_read.pca_analysis else 'No' if not pd.isnull(self.modelo.model_read.params): aux = '' for key in list(eval(self.modelo.model_read.params).keys()): aux += str(key) + ': ' + str( eval(self.modelo.model_read.params)[key]) + '\n' self.params_value['text'] = aux[:-1] else: self.params_value['text'] = '' # Evento de cargar los datos de los partidos def load_data(self): self.controlador.evento_load() if self.modelo.file is not None: self.load_model_but['state'] = 'active' self.calendar['state'] = 'normal' self.label_error.config(fg='green') self.label_error['text'] = 'Datos cargados con éxito' # Evento de actualizar los datos def refresh(self): self.controlador.evento_refresh() self.load_data() self.label_error.config(fg='green') self.label_error['text'] = 'Datos actualizados con éxito' # Evento de cargar el modelo predictivo seleccionado def load_model(self): self.label_error['text'] = '' self.train_model_but['state'] = 'active' self.controlador.evento_load_model() performance = self.modelo.modelo_prediccion.ac self.result['text'] = 'TASA DE ACIERTO: ' + str( performance.round(4) * 100) + '%' self.roc() self.pred_but['state'] = 'active' self.homeOptionMenu.config(state='active') self.awayOptionMenu.config(state='active') self.label_error.config(fg='green') self.label_error['text'] = 'Modelo cargado con éxito' # Evento de entrenar el modelo predictivo seleccionado def train_model(self): self.label_error['text'] = '' self.controlador.evento_train_model() self.load_model() # Evento de crear una curva ROC sobre los resultados del modelo predictivo seleccionado def roc(self): fpr, tpr, thres = roc_curve(self.modelo.modelo_prediccion.Y_test, self.modelo.modelo_prediccion.scores) auc_roc = auc(fpr, tpr) fig = Figure(figsize=(3.2, 3.2)) a = fig.add_subplot(111) a.plot(fpr, tpr, color='blue', label='AUC %0.2f' % auc_roc) a.legend(loc="lower right") a.set_position([0.15, 0.12, 0.8, 0.8]) a.set_xticks(ticks=np.arange(0, 1.5, 0.5)) a.set_yticks(ticks=np.arange(0, 1.5, 0.5)) a.set_xticklabels(labels=np.arange(0, 1.5, 0.5), fontdict={'fontsize': 8}) a.set_yticklabels(labels=np.arange(0, 1.5, 0.5), fontdict={'fontsize': 8}) a.set_title("Curva ROC " + self.modelo.algorithms[self.modelo.model_read.alg], fontsize=10) a.set_ylabel("TPR", fontsize=8) a.set_xlabel("FPR", fontsize=8) canvas = FigureCanvasTkAgg(fig, master=self.master) canvas.get_tk_widget().pack(expand=True) canvas.get_tk_widget().place(relx=0.8, rely=0.5, anchor=CENTER) canvas.draw() # Evento de crear las predicciones para un partido determinado def exec_prediction(self): date = datetime.strptime(self.calendar.get_date(), '%m/%d/%y') game_id = str( date.year ) + '%02d' % date.month + '%02d' % date.day + '0' + self.home.get() if self.home.get() != self.away.get() and self.home.get( ) != 'No seleccionado' and self.away.get() != 'No seleccionado': aux = self.modelo.modelo_prediccion.predictions_test game_true = game_id in aux.game_id.values if date < datetime.today() and game_true and aux[ aux.game_id == game_id]['a_team_id'].values[ 0] == self.away.get() or date > datetime.today(): self.controlador.evento_exec_prediction() predres = self.modelo.prediction aux = self.home.get() if predres else self.away.get() self.label_error['text'] = '' self.pred['text'] = str(self.home.get()) + ': ' + str( predres.round(2)) + '\t' + str( self.away.get()) + ': ' + str((1 - predres).round(2)) if date < datetime.today(): self.team_win['text'] = 'Victoria real: ' + str(aux) else: self.label_error.config(fg='red') self.label_error[ 'text'] = 'ERROR: Ese partido no se ha disputado.' self.pred['text'] = '' self.team_win['text'] = '' elif self.home.get() == 'No seleccionado' and self.away.get( ) == 'No seleccionado': self.label_error.config(fg='red') self.pred['text'] = '' self.team_win['text'] = '' self.label_error['text'] = 'ERROR: Hay que determinar los equipos' elif self.home.get() == 'No seleccionado' or self.away.get( ) == 'No seleccionado': self.label_error.config(fg='red') self.pred['text'] = '' self.team_win['text'] = '' self.label_error['text'] = 'ERROR: Falta un equipo por determinar' elif self.home.get() == self.away.get(): self.label_error.config(fg='red') self.pred['text'] = '' self.team_win['text'] = '' self.label_error[ 'text'] = 'ERROR: Los equipos deben ser diferentes.'
from tkinter import * from tkinter.font import BOLD from tkinter.ttk import Separator window = Tk() window.geometry("400x200") label1 = Label(window, text="value 1", relief=RAISED, bd=4) label1.place(relx=0.3, rely=0.2, relwidth=0.3, relheight=0.2) sep = Separator(window, orient='horizontal') sep.place(relx=0, rely=0.50, relwidth=1, relheight=1) label2 = Label(window, text="value 2", relief=RAISED, bd=4) label2.place(relx=0.3, rely=0.6, relwidth=0.3, relheight=0.2) window.mainloop()