def fontsize(self, sz_diff): """ Change font sizes by sz_diff. """ for fname in font.names(): f = font.nametofont(fname) sz = f.configure()["size"] if sz < 0: # use negative numbers if tk does. sz -= sz_diff else: sz += sz_diff if abs(sz) <= 4 or abs(sz) >= 64: # don't be stupid continue f.configure(size=sz) # The treeview does not change row height automatically. style = ttk.Style() rowheight = style.configure("Treeview").get("rowheight") if rowheight is None: # The style doesn't have this set to start with. # Shit like this makes ttk styling useless for portability. rowheight = 20 rowheight += sz_diff if rowheight <= 10 or rowheight >= 140: # getting ridiculous return style.configure("Treeview", rowheight=rowheight+sz_diff)
def findfont(self, names): "Return name of first font family derived from names." for name in names: if name.lower() in (x.lower() for x in tkfont.names(root=self)): font = tkfont.Font(name=name, exists=True, root=self) return font.actual()["family"] elif name.lower() in (x.lower() for x in tkfont.families(root=self)): return name
def test_names(self): names = font.names(self.root) self.assertIsInstance(names, tuple) self.assertTrue(names) for name in names: self.assertIsInstance(name, str) self.assertTrue(name) self.assertIn(fontname, names)
def findfont(self, names): "Return name of first font family derived from names." for name in names: if name.lower() in (x.lower() for x in tkfont.names(root=self)): font = tkfont.Font(name=name, exists=True, root=self) return font.actual()['family'] elif name.lower() in (x.lower() for x in tkfont.families(root=self)): return name
def find_font(self, names): name = None for name in names: if name.lower() in (x.lower() for x in tk_fonts.names(root=self)): font = tk_fonts.Font(name=name, exists=True, root=self) return font.actual()['family'] elif name.lower() in (x.lower() for x in tk_fonts.families(root=self)): break else: return None return name
def setup_scaling(self): self.fonts_size = { name: font.nametofont(name)["size"] for name in font.names() } text_scale = self.app_scale if self.app_scale < 1 else math.sqrt( self.app_scale) themes.scale_fonts(self.fonts_size, self.app_scale) self.icon_text_font = font.Font(family="TkIconFont", size=int(12 * text_scale)) self.edge_font = font.Font(family="TkDefaultFont", size=int(8 * text_scale))
def test_names(self): self.assertRaises(RuntimeError, font.names) root = tkinter.Tk() names = font.names() self.assertIsInstance(names, tuple) self.assertTrue(names) for name in names: self.assertIsInstance(name, str) self.assertTrue(name) self.assertIn(fontname, names) root.destroy() tkinter.NoDefaultRoot() self.assertRaises(RuntimeError, font.names)
def __init__(self, **kwargs): dprint(3, "\nTkMemobook::__init__::") Memobook.__init__(self, **kwargs) self.offset = [] if "root" in kwargs.keys(): self.root = kwargs["root"] else: self.root = Tk() ### setting theme is inexplicably only affecting Book and the file-open dialogue, ### nothing else. Setting theme of, e.g., self.menu also isn't working. #self.root.style = Style() #self.root.style.theme_use(self.ctrl["style"]["theme"]) self.root.title("Memobook") # adjust Tk's font sizes according to conf.xml "style" section. # Positive value in conf.xml is an increase in size, negative a decrease for name in font.names(): tk_font = font.nametofont(name) new_size = tk_font["size"] - int(self.ctrl["style"]["font"]["size"]) tk_font.configure(size=new_size) # deal with hidden files for file dialogue by calling a dummy dialogue with nonsense options: (method taken from online forum) # (this is done here and not in binding class because it is a front-end matter, not a back-end one) try: self.root.tk.call('tk_getOpenFile', '-flurpee') except TclError: #catch and discard the TclError that the nonsense option caused pass finally: self.root.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') self.root.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') if "tabs" in kwargs.keys(): self.tabs = kwargs["tabs"] else: self.tabs = Book(self.root, ruling=self.ctrl, width=self.ctrl["x"], height=self.ctrl["y"]) #self.tabs.ruling(self.ctrl) #if ruling is not specified in constructor call, it must be done so here self.tabs.set_save_hook(lambda:self.save_note()) self.tabs.set_close_hook(lambda:self.close_page()) self.tabs.bind("<Double-Button-1>", lambda e: self.tabs.newpage(None)) self.menu = Menu(self.root) self.set_bindings() dprint(3, "Tk initialization complete. Displaying...") self.tabs.grid_columnconfigure(0, weight=1) self.tabs.grid_rowconfigure(0, weight=1) self.tabs.grid(sticky="nswe") self.populate_menus() self.root.config(menu=self.menu) self.root.grid_columnconfigure(0, weight=1) self.root.grid_rowconfigure(0, weight=1) self.offset = [ self.tabs.winfo_reqwidth()-int(self.ctrl["x"]), self.tabs.winfo_reqheight()-int(self.ctrl["y"]) ]
from tkinter import Tk from tkinter.font import names, nametofont r = Tk() for fontname in names(): font = nametofont(fontname) print('{}:\t {} {} {} {}'.format(fontname, font['family'], font['size'], font['weight'], font['slant']))
from tkinter import * from tkinter import font root = Tk() # main_show_text = Text(root, height=5, width=45, wrap=WORD, pady=0,background="red",fg="gray22") # main_show_text.pack() main_font = font.names()[1] word_study = Label(root, text="school", borderwidth=5, height=2, width=15, relief="ridge", font=main_font + " 43") word_study.pack() root.mainloop()
import tkinter as tk from tkinter import font root = tk.Tk() for name in font.names(): font_obj = font.nametofont(name) tk.Label(root, text=name, font=font_obj).pack() namedfont = tk.StringVar() family = tk.StringVar() size = tk.IntVar() tk.OptionMenu(root, namedfont, *font.names()).pack() tk.OptionMenu(root, family, *font.families()).pack() tk.Spinbox(root, textvariable=size, from_=6, to=128).pack() def setFont(): font_obj = font.nametofont(namedfont.get()) font_obj.configure(family=family.get(), size=size.get()) tk.Button(root, text='Change', command=setFont).pack() root.mainloop()
import sys if sys.version_info.major == 3: import tkinter as Tk, tkinter.font as tkFont else: import Tkinter as Tk, tkFont root = Tk.Tk() print(tkFont.families()) print(tkFont.names()) #Bell MT #Ebrima #Cambria #Franklin Gothic Medium #Dubai - gibts nicht #Gill Sans MT -gibts nicht if "Bell MT" in tkFont.families(): print("In Familie") if "Bell MT" in tkFont.names(): print("In Names")
def test_names(self): names = font.names(self.root) self.assertIn(fontname, names)
import tkinter.font as font import tkinter x = tkinter.Tk() a = font.names(x) print(a) print(font.families(x)) """ ('Baoli TC', 'Baoli SC', 'BiauKai', 'Hiragino Sans GB', 'Heiti TC', 'Heiti SC', 'STFangsong', 'STHeiti', 'STKaiti', 'STSong', 'Kaiti TC', 'Kaiti SC', 'Lantinghei TC', 'Lantinghei SC', 'Libian TC', 'Libian SC', 'LiHei Pro', 'LiSong Pro', 'LingWai TC', 'LingWai SC', 'HanziPen TC', 'HanziPen SC', 'PingFang TC', 'PingFang HK', 'PingFang SC', 'Apple LiSung', 'Apple LiGothic', 'Hannotate TC', 'Hannotate SC', 'Songti TC', 'Songti SC', 'Wawati TC', 'Wawati SC', 'Weibei TC', 'Weibei SC', 'Xingkai TC', 'Xingkai SC', 'Yuppy TC', 'Yuppy SC', 'Yuanti TC', 'Yuanti SC', 'Al Bayan', 'Al Nile', 'Al Tarikh', 'American Typewriter', 'Andale Mono', 'Apple Braille', 'Apple Chancery', 'Apple Color Emoji', 'Apple SD Gothic Neo', 'Apple Symbols', 'AppleGothic', 'AppleMyungjo', 'Arial', 'Arial Black', 'Arial Hebrew', 'Arial Hebrew Scholar', 'Arial Narrow', 'Arial Rounded MT Bold', 'Arial Unicode MS', 'Avenir', 'Avenir Next', 'Avenir Next Condensed', 'Ayuthaya', 'Baghdad', 'Baloo', 'Baloo Bhai', 'Baloo Bhaijaan', 'Baloo Bhaina', 'Baloo Chettan', 'Baloo Da', 'Baloo Paaji', 'Baloo Tamma', 'Baloo Tammudu', 'Baloo Thambi', 'Bangla MN', 'Bangla Sangam MN', 'Baskerville', 'Beirut', 'Big Caslon', 'Bodoni 72', 'Bodoni 72 Oldstyle', 'Bodoni 72 Smallcaps', 'Bodoni Ornaments', 'Bradley Hand', 'Brush Script MT', 'Cambay Devanagari', 'Chalkboard', 'Chalkboard SE', 'Chalkduster', 'Charter', 'Cochin', 'Comic Sans MS', 'Copperplate', 'Corsiva Hebrew', 'Courier', 'Courier New', 'Damascus', 'DecoType Naskh', 'Devanagari MT', 'Devanagari Sangam MN', 'Didot', 'DIN Alternate', 'DIN Condensed', 'Diwan Kufi', 'Diwan Thuluth', 'Druk', 'Druk Wide', 'Euphemia UCAS', 'Farah', 'Farisi', 'Futura', 'Galvji', 'GB18030 Bitmap', 'Geeza Pro', 'Geneva', 'Georgia', 'Gill Sans', 'Gotu', 'Gujarati MT', 'Gujarati Sangam MN', 'GungSeo', 'Gurmukhi MN', 'Gurmukhi MT', 'Gurmukhi Sangam MN', 'HeadLineA', 'Hei', 'Helvetica', 'Helvetica Neue', 'Herculanum', 'Hiragino Maru Gothic ProN', 'Hiragino Mincho ProN', 'Hiragino Sans', 'Hiragino Sans CNS', 'Hoefler Text', 'Impact', 'InaiMathi', 'ITF Devanagari', 'ITF Devanagari Marathi', 'Jaini', 'Jaini Purva', 'JetBrains Mono', 'Kai', 'Kailasa', 'Kannada MN', 'Kannada Sangam MN', 'Kefa', 'Khmer MN', 'Khmer Sangam MN', 'Klee', 'Kohinoor Bangla', 'Kohinoor Devanagari', 'Kohinoor Gujarati', 'Kohinoor Telugu', 'Kokonor', 'Krungthep', 'KufiStandardGK', 'Lahore Gurmukhi', 'Lao MN', 'Lao Sangam MN', 'Lucida Grande', 'Luminari', 'Maku', 'Malayalam MN', 'Malayalam Sangam MN', 'Marker Felt', 'Menlo', 'Microsoft Sans Serif', 'Mishafi', 'Mishafi Gold', 'Modak', 'Monaco', 'Mshtakan', 'Mukta', 'Mukta Mahee', 'Mukta Malar', 'Mukta Vaani', 'Muna', 'Myanmar MN', 'Myanmar Sangam MN', 'Nadeem', 'Nanum Brush Script', 'Nanum Gothic', 'Nanum Myeongjo', 'Nanum Pen Script', 'New Peninim MT', 'Noteworthy', 'Noto Nastaliq Urdu', 'Noto Sans Javanese', 'Noto Sans Kannada', 'Noto Sans Myanmar', 'Noto Sans Oriya', 'Noto Serif Kannada', 'Noto Serif Myanmar', 'Optima', 'Oriya MN', 'Oriya Sangam MN', 'Osaka', 'Palatino', 'Papyrus', 'PCMyungjo', 'Phosphate', 'PilGi', 'Plantagenet Cherokee', 'Proxima Nova', 'PSL Ornanong Pro', 'PT Mono', 'PT Sans', 'PT Sans Caption', 'PT Sans Narrow', 'PT Serif', 'PT Serif Caption', 'Raanana', 'Rockwell', 'Sana', 'Sathu', 'Savoye LET', 'Shobhika', 'Shree Devanagari 714', 'SignPainter', 'Silom', 'Sinhala MN', 'Sinhala Sangam MN', 'Skia', 'Snell Roundhand', 'STIXGeneral', 'STIXIntegralsD', 'STIXIntegralsSm', 'STIXIntegralsUp', 'STIXIntegralsUpD', 'STIXIntegralsUpSm', 'STIXNonUnicode', 'STIXSizeFiveSym', 'STIXSizeFourSym', 'STIXSizeOneSym', 'STIXSizeThreeSym', 'STIXSizeTwoSym', 'STIXVariants', 'Sukhumvit Set', 'Symbol', 'Tahoma', 'Tamil MN', 'Tamil Sangam MN', 'Telugu MN', 'Telugu Sangam MN', 'Thonburi', 'Times', 'Times New Roman', 'Tiro Bangla', 'Tiro Gurmukhi', 'Tiro Hindi', 'Tiro Kannada', 'Tiro Marathi', 'Tiro Sanskrit', 'Tiro Tamil', 'Tiro Telugu', 'Toppan Bunkyu Gothic', 'Toppan Bunkyu Midashi Gothic', 'Toppan Bunkyu Midashi Mincho', 'Toppan Bunkyu Mincho', 'Trattatello', 'Trebuchet MS', 'Tsukushi A Round Gothic', 'Tsukushi B Round Gothic', 'Ubuntu Mono', 'Verdana', 'Waseem', 'Webdings', 'Wingdings', 'Wingdings 2', 'Wingdings 3', 'YuGothic', 'YuKyokasho', 'YuKyokasho Yoko', 'YuMincho', 'YuMincho +36p Kana', 'Zapf Dingbats', 'Zapfino') """
def __init__(self, playlists: list[Playlist], defaults: dict): root = ThemedTk(theme='black') root.option_add('*tearOff', tk.FALSE) root.wm_title("btecify") root.wm_iconbitmap('assets\\btecify.ico') root.resizable(width=False, height=False) root.wm_iconify() root.wm_deiconify() for namefont in tkfont.names(root): rootfont = tkfont.nametofont(namefont) rootfont.config(family="Lucida Console") def _onclose(): self.output = ["EXIT"] root.destroy() root.protocol("WM_DELETE_WINDOW", _onclose) self.selectedplaylist = tk.StringVar() self.playlists = playlists self._generateplaylistnames() self.songqueuevar = tk.StringVar(value=[]) self.volume = tk.IntVar(value=50) self.seek = tk.DoubleVar(value=0) self.songlistvar = tk.StringVar(value=[]) self.playlistsongsvar = tk.StringVar(value=[]) self.progressbarvar = tk.IntVar(value=0) self.songsearchqueryvar = tk.StringVar(value="") self.extrainfoplaylistsvar = tk.StringVar(value=[]) self.searchfunc = searchsongname self.discordpresencevar = tk.BooleanVar(value=defaults['discord']) self.keybinds: list[tuple[str, str]] = [] # CONSOLE consolewindow = tk.Toplevel(root) consolewindow.wm_title("Console Logs") consolewindow.wm_protocol("WM_DELETE_WINDOW", lambda: consolewindow.wm_withdraw()) consolewindow.wm_withdraw() consolewindow.wm_resizable(False, False) consolewindowframe = ttk.Frame(consolewindow, padding=5, relief="groove") consolewindowframe.grid() consolewindowtext = tk.Text(consolewindowframe, foreground='white', background='black', state='disabled', width=100, height=40) consolewindowtext.grid(row=0, column=0) consolewindowtextscrollbar = ttk.Scrollbar( consolewindowframe, orient=tk.VERTICAL, command=consolewindowtext.yview) consolewindowtext['yscrollcommand'] = consolewindowtextscrollbar.set consolewindowtextscrollbar.grid(row=0, column=1, sticky='ns') def resetconsolewindow(*args): consolewindowtext.yview_moveto(1.0) consolewindowtext.bind('<Visibility>', resetconsolewindow) consolewindowtext.bind('<FocusIn>', resetconsolewindow) # KEYBINDS keybindwindow = tk.Toplevel(root) keybindwindow.wm_title("Keybindings") keybindwindow.wm_protocol("WM_DELETE_WINDOW", lambda: keybindwindow.wm_withdraw()) keybindwindow.wm_resizable(False, False) keybindwindow.wm_withdraw() keybindwindowframe = ttk.Frame(keybindwindow, padding=5, relief='groove') keybindwindowframe.grid() keybindlistframe = ttk.Frame(keybindwindowframe, padding=3, relief='groove') keybindlistframe.grid(row=0, column=0) keybindings = [i for i in defaults['keybinds']] keybindlist = [] for x in range(len(keybindings)): kbname = str(keybindings[x]) newframe = ttk.Frame(keybindlistframe) newframe.grid(column=0, row=x) newlabel = ttk.Label( newframe, text=kbname + ": ", width=max(map(lambda a: len(a), keybindings)) + 2) newlabel.grid(row=0, column=0) keybindtextvariable = tk.StringVar("") newentry = ttk.Entry(newframe, textvariable=keybindtextvariable) newentry.grid(row=0, column=1) newentry.bind('<FocusIn>', lambda *args: self._addchange('keybinds')) keybindlist.append((kbname, keybindtextvariable)) keybindbuttonsframe = ttk.Frame(keybindwindowframe, padding=3, relief='groove') keybindbuttonsframe.grid(row=1, column=0) keybindbuttondefault = ttk.Button( keybindbuttonsframe, text="RESET TO DEFAULTS", command=lambda: self._setoutput("defaultkeybinds")) keybindbuttondefault.grid(row=0, column=0) keybindbuttonconfirm = ttk.Button( keybindbuttonsframe, text="CONFIRM KEYBINDINGS", command=lambda: self._setoutput( "updatekeybinds", [(i[0], i[1].get()) for i in keybindlist])) keybindbuttonconfirm.grid(row=0, column=1) # MENU menubar = tk.Menu(root) root.configure(menu=menubar) menuplaylist = tk.Menu(menubar) menusong = tk.Menu(menubar) menufile = tk.Menu(menubar) menubar.add_cascade(menu=menuplaylist, label="Playlist") menubar.add_cascade(menu=menusong, label="Song") menubar.add_cascade(menu=menufile, label="File") menubar.add_separator() menubar.add_command(label="Playlist: None", state="disabled") menubarplaylistlabelindex = len(menubar.winfo_children()) + 1 menuplaylist.add_command(label="New...", command=self._newplaylist) menuplaylist.add_command(label="Delete", command=self._deleteplaylist) menuplaylist.add_command(label="Rename...", command=self._renameplaylist) menuplaylist.add_command(label="Copy...", command=self._copyplaylist) menuplaylist.add_separator() menuplaylist.add_command(label="Reset watched", command=self._unwatchplaylist) menuplaylist.add_command(label="Requeue", command=self._requeue) menuplaylist.add_separator() menuplaylist.add_command(label="Reset from Youtube", command=self._resetfromyoutube) menusong.add_command(label="New...", command=self._newsong) menusong.add_command(label="Delete", command=lambda: self._setoutput( "deletesongs", *self._getselectedsongs())) menusong.add_separator() menusong.add_command(label="Add selected songs to selected playlist", command=self._addsongtoplaylist) menusong.add_command( label="Remove selected songs from selected playlist", command=lambda: self._setoutput("removesongsfromplaylist", self._getselectedplaylist(), self._getselectedsongs())) menusong.add_separator() menusong.add_command(label="Play selected song", command=self._playselectedsong) menusong.add_command(label="Play random song", command=lambda: self._setoutput("randomsong")) menufile.add_command(label="View console logs...", command=consolewindow.wm_deiconify) menufile.add_command( label="Open data directory...", command=lambda: self._setoutput("opendatadirectory")) menufile.add_separator() menufile.add_command(label="Change keybinds...", command=keybindwindow.wm_deiconify) menufile.add_separator() menufile.add_checkbutton( label="Discord Presence", command=lambda: self._setoutput('discordpresence', self.discordpresencevar.get()), variable=self.discordpresencevar) menufile.add_separator() menufile.add_command(label="Change API key...", command=lambda: self._setoutput("newapikey")) menufile.add_separator() menufile.add_command(label="Login Details...", command=self._logindetails) menufile.add_command(label="Sync playlist to btecify servers", command=lambda: self._setoutput("syncwithserver")) # PRIMARY FRAME primaryframe = ttk.Frame(root) primaryframe.grid() # QUEUE queuelabelframe = ttk.Labelframe(primaryframe, text="Song queue", relief='groove', borderwidth=5) queuelabelframe.grid(column=0, row=0, columnspan=2, rowspan=2, sticky='nswe') queuelist = mylistbox(queuelabelframe, height=15, listvariable=self.songqueuevar, width=50, exportselection=False, selectmode=tk.MULTIPLE) queuelistscrollbar = ttk.Scrollbar(queuelabelframe, orient=tk.VERTICAL, command=queuelist.yview) queuelist.grid(column=0, row=0, sticky='nswe') queuelistscrollbar.grid(column=1, row=0, sticky='ns') queuelist['yscrollcommand'] = queuelistscrollbar.set # PLAYER INFORMATION playingframe = ttk.Labelframe(primaryframe, text="Playing Song", relief='groove', padding=5) playingframe.grid(column=2, row=0, sticky='new') songinfo = ttk.Label( playingframe, text= f"No playlist\nNo song playing\nNo song author\nNo duration\n{PLAYINGINFOPLACEHOLDER}", justify=tk.CENTER, anchor=tk.CENTER) songinfo.grid(column=0, row=0, sticky='ew') songdesc = ttk.Label(playingframe, text="", justify=tk.CENTER, anchor=tk.CENTER) songdesc.grid(column=0, row=1) songprogress = ttk.Progressbar(playingframe, orient=tk.HORIZONTAL, mode='determinate', variable=self.progressbarvar) songprogress.grid(column=0, row=3, sticky='wes') songseeker = ttk.Scale(playingframe, from_=0, to=1, variable=self.seek) songseeker.grid(column=0, row=4, sticky='wes') songseeker.bind("<ButtonPress-1>", lambda *args: self.changes.update({'seeking': True})) songseeker.bind("<ButtonRelease-1>", lambda *args: self.changes.update({'seeking': False})) playingframe.grid_rowconfigure((0, 1, 2, 3), weight=1) # SONG SELECTION AND SONG VIEWING songselectionandviewingframe = ttk.Frame(primaryframe) songselectionandviewingframe.grid(column=3, row=0, columnspan=2, rowspan=2) songlistnotebook = ttk.Notebook(songselectionandviewingframe) songlistnotebook.grid(column=0, row=0) songlistframe = ttk.Frame(songlistnotebook, padding=1) songlist = mylistbox(songlistframe, height=15, listvariable=self.songlistvar, selectmode=tk.MULTIPLE, bg="#282828", disabledforeground="gray80", fg="white", activestyle='dotbox', selectbackground="#282828", selectforeground="red2", width=50, exportselection=False) songlistscrollbar = ttk.Scrollbar(songlistframe, orient=tk.VERTICAL, command=songlist.yview) ################################################################################################################ playlistsongsframe = ttk.Frame(songlistnotebook, padding=1) playlistsongslist = mylistbox(playlistsongsframe, height=15, listvariable=self.playlistsongsvar, selectmode=tk.MULTIPLE, bg="#282828", disabledforeground="gray80", fg="white", activestyle='dotbox', selectbackground="#282828", selectforeground="red2", width=50, exportselection=False) playlistsongslistscrollbar = ttk.Scrollbar( playlistsongsframe, orient=tk.VERTICAL, command=playlistsongslist.yview) ################################################################################################################ _songlistsearchchangedcommand = root._register( self._songlistsearchchanged) songsearchentry = ttk.Entry( songselectionandviewingframe, validate="all", validatecommand=(_songlistsearchchangedcommand, '%V'), textvariable=self.songsearchqueryvar, ) self.completeselectedsongs: list[Song] = [] resetsonglistselectionbutton = ttk.Button( songselectionandviewingframe, text="RESET SELECTION|SELECTED: 0", command=lambda: self._addchange("resetselectedsongs")) songlist.grid(row=0, column=0, columnspan=2) songlistscrollbar.grid(row=0, column=2, sticky='wns') playlistsongslist.grid(row=0, column=0, columnspan=2) playlistsongslistscrollbar.grid(row=0, column=2, sticky='wns') songsearchentry.grid(row=1, column=0, sticky='ews') resetsonglistselectionbutton.grid(row=2, column=0, sticky='nw') songlist['yscrollcommand'] = songlistscrollbar.set playlistsongslist['yscrollcommand'] = playlistsongslistscrollbar.set songlistnotebook.add(songlistframe, text="Song list") songlistnotebook.add(playlistsongsframe, text="empty") # BOTTOM LEFT LOGO btecifyiconimage = tk.PhotoImage(file="assets/btecify64.png") btecifyiconlabel = ttk.Label(primaryframe, image=btecifyiconimage) btecifyiconlabel.grid(column=0, row=2, sticky='ws') # PLAYLIST SELECT playlistselectframe = ttk.LabelFrame(primaryframe, text="Playlist select", relief='groove', padding=3) playlistselectframe.grid(row=2, column=3, sticky='wn') playlistselectcombobox = ttk.Combobox( playlistselectframe, values=self.playlistnames, textvariable=self.selectedplaylist, width=26, state='readonly') self.selectedplaylist.trace_add( mode="write", callback=self._playlistcomboboxvalueupdated) playlistselectcombobox.set(playlists[0].name) playlistselectcombobox.grid(sticky='ewn') playlistselectbutton = ttk.Button(playlistselectframe, text="SWITCH TO PLAYLIST", command=self._chooseplaylist) playlistselectbutton.grid(row=1, sticky='s') # PLAYER BUTTONS bottommiddleframe = ttk.LabelFrame(primaryframe, text="Player controls", relief='groove', padding=5) bottommiddleframe.grid(column=2, row=1, sticky='wnse') pausebutton = ttk.Button(bottommiddleframe, text="PAUSE", command=self._pause) pausebutton.grid(row=0, column=0, columnspan=3, sticky='ew') skipbutton = ttk.Button(bottommiddleframe, text="SKIP", command=self._skip) skipbutton.grid(row=1, sticky='w') loopbutton = ttk.Button(bottommiddleframe, text="LOOP: DISABLED", command=lambda: self._setoutput("loop")) loopbutton.grid(row=1, column=1, padx=120) removesongbutton = ttk.Button(bottommiddleframe, text="REMOVE SONG", command=self._playerremovesongbutton) removesongbutton.grid(row=1, column=2, sticky='e') volumeslider = ttk.LabeledScale(bottommiddleframe, from_=0, to=100, variable=self.volume, compound='bottom') volumeslider.scale.set(defaults['volume']) volumeslider.scale.configure(command=self._volchange) volumeslider.label.update() volumeslider.grid(row=2, columnspan=3, sticky='ew') bottommiddleframe.grid_rowconfigure((0, 1, 2), weight=1) bottommiddleframe.grid_columnconfigure((0, 1), weight=1) # EXTRA SONG INFORMATION extrasonginfoframe = ttk.Labelframe(primaryframe, text="Song Info", relief="sunken", padding=3) extrasonginfoframe.grid(row=2, column=1, columnspan=2, sticky="nesw") extrasonginfoname = ttk.Label(extrasonginfoframe, text="NO SONG", justify=tk.LEFT, anchor="w") extrasonginfoname.grid(row=0, column=0, sticky="nesw") extrasonginfoplaylistlabelframe = ttk.Labelframe(extrasonginfoframe, text="In Playlists", relief="groove", padding=5) extrasonginfoplaylistlabelframe.grid(row=1, column=0, sticky="w") extrasonginfoplaylists = mylistbox( extrasonginfoplaylistlabelframe, height=5, selectmode="browse", listvariable=self.extrainfoplaylistsvar, exportselection=False) extrasonginfoplaylists.grid(row=0, column=0, sticky="") extrasonginfoplaylistsresetbutton = ttk.Button( extrasonginfoplaylistlabelframe, text="RESET", command=lambda: extrasonginfoplaylists.selection_clear( 0, 100000) or self.extraplaylistselection.clear( )) # Executes two statements in one lambda. extrasonginfoplaylistsresetbutton.grid(row=1, column=0, sticky='nesw') extrasonginfobuttonsframe = ttk.Frame(extrasonginfoplaylistlabelframe, padding=2) extrasonginfobuttonsframe.grid(row=0, column=1, sticky='nesw') extrasonginforemovebutton = ttk.Button( extrasonginfobuttonsframe, text="REMOVE SONG FROM PLAYLISTS", command=self._extrasonginforemovebuttonfunc) extrasonginforemovebutton.grid(row=0, column=0, sticky='') extrasonginfoopensong = ttk.Button( extrasonginfobuttonsframe, text="OPEN IN YOUTUBE", command=lambda: self._setoutput("openinyoutube", [ *self.completeselectedsongs ] or [self._getselectedsong()])) extrasonginfoopensong.grid(row=1, column=0, sticky='') def _updatebasedonvalues(): extrasongselectedplaylistvalues = self._getextrasongselectedplaylists( extrasonginfoplaylists) if self.changes[ 'songinfo'] or extrasongselectedplaylistvalues != self.extraplaylistselection: if self.playingsong is not None: self.progressbarvar.set(value=self.progressbar) playlistofthissong = self.playlistwhichsongisfrom if playlistofthissong is None: playlistofthissong = "Played manually" removesongbutton.configure(state='disabled') else: playlistofthissong = playlistofthissong.name removesongbutton.configure(state='active') songinfo['text'] = ( f"{playlistofthissong}\n{self.playingsong.name[:len(PLAYINGINFOPLACEHOLDER)]}\n{self.playingsong.author}\n{self.playingsong.duration}\n" + PLAYINGINFOPLACEHOLDER) if self.paused: songdesc['text'] = "PAUSED" pausebutton['text'] = "PLAY" else: songdesc['text'] = "PLAYING" pausebutton['text'] = "PAUSE" if self.loop: loopbutton['text'] = "LOOP: ENABLED" else: loopbutton['text'] = "LOOP: DISABLED" targetsong = self._getselectedsong() if targetsong is not None: extrasonginfoname['text'] = targetsong.name[:( queuelist.cget("width") // 3) + len(PLAYINGINFOPLACEHOLDER)] self.playlistswithtargetsong = list( filter(lambda a: targetsong in a.getsongs(), self.playlists)) self.extrainfoplaylistsvar.set( [i.name for i in self.playlistswithtargetsong]) extrasonginfoplaylists.selection_clear(0, 1000000) self.extraplaylistselection.extend([ i for i in extrasongselectedplaylistvalues if i not in self.extraplaylistselection ]) for i, v in enumerate(self.extraplaylistselection): if v in self.playlistswithtargetsong: extrasonginfoplaylists.selection_set( self.playlistswithtargetsong.index(v)) else: self.extraplaylistselection.remove(v) else: extrasonginfoname['text'] = "NO SONG" self.extrainfoplaylistsvar.set([]) extrasonginfoplaylists.selection_clear(0, 10000) self._addchange('songinfo', False) if self.changes['resetselectedsongs']: songlist.selection_clear(0, 100000000) queuelist.selection_clear(0, 100000) playlistsongslist.selection_clear(0, 100000) self.completeselectedsongs = [] resetsonglistselectionbutton.configure( text=f"RESET SELECTION | SELECTED: 0") self._addchange('songinfo') self._addchange('resetselectedsongs', False) currentlyselectedsonglistvalues = self._getselectedvalues( songlist, self.displaysonglist) currentlyselectedqueuevalues = self._getselectedvalues( queuelist, self.songqueue) currentlyselectedplaylistsongsvalues = self._getselectedvalues( playlistsongslist, self.displayplaylistsongs) displayablesongsinsonglist = set([ i for i in self.displaysonglistnew if i in self.completeselectedsongs ]) displayablesongsinqueuelist = set([ i for i in self.songqueuenew if i in self.completeselectedsongs ]) displayablesongsinplaylistsongslist = set([ i for i in self.displayplaylistsongsnew if i in self.completeselectedsongs ]) if self.changes['songlist'] or ( currentlyselectedsonglistvalues != displayablesongsinsonglist ) or (displayablesongsinqueuelist != currentlyselectedqueuevalues ) or (displayablesongsinplaylistsongslist != currentlyselectedplaylistsongsvalues): if self.changes['songlist']: self._songlistsearchchanged() self.songlistvar.set( value=[i.name for i in self.displaysonglistnew]) self.playlistsongsvar.set( value=[i.name for i in self.displayplaylistsongsnew]) self.displaysonglist = self.displaysonglistnew self.displayplaylistsongs = self.displayplaylistsongsnew songlist.selection_clear(0, 1000000) queuelist.selection_clear(0, 1000000) playlistsongslist.selection_clear(0, 10000) self._addchange('songinfo') self._addchange('songlist', False) else: self.completeselectedsongs.extend([ i for i in currentlyselectedsonglistvalues if i not in self.completeselectedsongs ]) self.completeselectedsongs.extend([ i for i in currentlyselectedqueuevalues if i not in self.completeselectedsongs ]) self.completeselectedsongs.extend([ i for i in currentlyselectedplaylistsongsvalues if i not in self.completeselectedsongs ]) for song in self.completeselectedsongs: if song: if song in self.displaysonglistnew: songlist.selection_set( self.displaysonglistnew.index(song)) if song in self.songqueuenew: queuelist.selection_set( self.songqueuenew.index(song)) if song in self.displayplaylistsongsnew: playlistsongslist.selection_set( self.displayplaylistsongsnew.index(song)) self._addchange('songinfo') resetsonglistselectionbutton.configure( text= f"RESET SELECTION | SELECTED: {len(self.completeselectedsongs)}" ) if self.changes['songqueue']: queuelist.selection_clear(0, 100000) self.songqueue = self.songqueuenew self.songqueuevar.set(value=[ f"{i+1:>3}: {v.name}" for i, v in enumerate(self.songqueue) ]) self._addchange('songqueue', False) if self.changes['playlistoptions']: self._generateplaylistnames() playlistselectcombobox['values'] = self.playlistnames self._addchange('songinfo') self._addchange('playlistoptions', False) if self.changes['progressbar']: self.progressbarvar.set(value=self.progressbar) self._addchange('progressbar', False) if self.changes['playlistcomboboxupdate']: playlist = self._getselectedplaylist() label = "Playlist: " if playlist: label += playlist.name else: label += "None" menubar.entryconfigure(menubarplaylistlabelindex, label=label) songlistnotebook.tab(1, text=self._getselectedplaylist().name) self._addchange("songlist") self._addchange('playlistcomboboxupdate', False) if self.changes['updatelogs']: logstoadd = self.newlogs[len(self.logs):] consolewindowtext['state'] = 'normal' for log in logstoadd: logstr = "" timevalues = log[0] logstr += f"{timevalues.tm_hour:0>2}:{timevalues.tm_min:0>2}:{timevalues.tm_sec:0>2}: " for obj in log[1]: objstring = str(obj).replace("\n", "\n\t ") logstr += objstring + " " consolewindowtext.insert('end', logstr + "\n\n") consolewindowtext['state'] = 'disabled' self.logs = self.newlogs self._addchange('updatelogs', False) if self.changes['seeking']: val = self.seek.get() if 0 < val < 1: self._setoutput('seek', self.seek.get()) if self.changes['keybinds']: for kbset in keybindlist: for j in self.keybinds: if j[0] == kbset[0]: kbset[1].set(j[1]) self._addchange("keybinds", False) root.after(10, _updatebasedonvalues) _updatebasedonvalues() G.musicgui = self root.mainloop()
import sys if sys.version_info.major is 3: import tkinter as Tk, tkinter.font as tkFont else: import Tkinter as Tk, tkFont root = Tk.Tk() print(tkFont.families()) print(tkFont.names())
# mylabel.pack() # # btnToggle = tk.Button(text="Hide Example", command=toggle) # btnToggle.pack() # # root.mainloop() from tkinter import * from tkinter import font root = Tk() root.title('Font Families') fonts = list(font.families()) fonts.sort() display = Listbox(root) display.pack(fill=BOTH, expand=YES, side=LEFT) scroll = Scrollbar(root) scroll.pack(side=RIGHT, fill=Y, expand=NO) scroll.configure(command=display.yview) display.configure(yscrollcommand=scroll.set) for item in fonts: display.insert(END, item) print(font.names()) root.mainloop()