Python Tkinter section

The Fonts Available in Your System

Post by Amina Delali, April 30th, 2023

Description

If, you are working on a code, and you don't know the fonts available in your system, and you don't know how they look like, you can use this one. I will explain its principle, I will share it, and all you have to do is to run it.

To get the list of font families available in your system using Python tkinter, you can call the font.families method. But you have first to import font, in order for it to work. I used the method to get the entire list of family fonts that are installed in my System, I sorted it, then:

  • I displayed the first 20 available fonts using the Canvas widget, by calling the create_text method 4 times for each Canvas (there are in total 20 Canvas created to display 20 family fonts ). Each created text in a Canvas, will have a corresponding font. The 4 created texts in each Canvas will represent a variation of this font. The text is almost always the same; the letters "aA", unless the text is created for an empty Canvas. In that case, the text will be an Empty String. The variations of each text's font are:
    • weight= "normal", slant="roman" (roman for normal)
    • weight= "normal", slant="italic"
    • weight= "bold", slant="roman"
    • weight= "bold", slant="italic"

      • 20 labels have also been created to display the name of the family font above each corresponding Canvas widget.

  • I created navigational buttons, with the same principle as the one in this code. Two buttons to display the firsts and the lasts fonts in the sorted list. And two other buttons to navigate through the list; the next or the previous twenty fonts.
  • Each one of the 4 buttons will eventually call the updateFonts function that will update the values of the widgets to correspond to the new fonts
  • , it changes:
    • The text displayed in the labels above each canvas
    • The font of the created texts. If there is no more font (the last page), the default font will be "Courier", to allow automation of the fonts update, and to avoid conditional tests.
    • The text to display with the corresponding font. There will be two options: wether it is the letters "aA", or the empty string for a non existing fonts.
  • To allow the automation of the display, and to handle the fact that the number of fonts is not necessarily a number divisible by 20, I did this:
    • The list of fonts is a list of fonts lists. Each font list contain 5 other smaller lists of 3 elements in that order:
      • The font to be applied on the texts of the Canvas
      • The text to be displayed in the Canvas
      • The name of the font that the labels above the canvas should display.
    • The missing fonts in a row, are replaced by an empty small list. In the code it is defined this way: emptyItem = ["Courier","",""]
    • The entire empty rows, are represented by a list of 5 empty small list defined this way: [emptyList.append(emptyItem) for i in range(5)]

And of course, the entire code is displayed below.



The Code

Copy Code

from tkinter import *
from tkinter import font
from PIL import ImageTkImage

main_window=Tk()
myList font.families()
numberOF len(myList)
myList list(myList)
myList.sort()
main_window.title("Python Tkinter Cursors")
bgColor="#24252B"
fgColor ="#ffffff"

fontsBL = []
fontsSL = []
fontsRL = []
emptyItem = ["Courier","",""]

emptyList=[]
[emptyList.append(emptyItem)  for in range(5)]

fontsBLS numberOF // 20
fontsSLS = (numberOF 20 ) // 5
fontsRLS = (numberOF 20 ) % 5

for in range(fontsBLS*4):
    temp = []
    for in range(5):
        temp.append([myList[i*5+j],"aA",myList[i*5+j]])
       
    fontsBL.append(temp)



for in range(fontsBLS*4,fontsBLS*4+fontsSLS):
    temp = []
    for in range(5):
        temp.append([myList[i*5+j],"aA",myList[i*5+j]])
        
    fontsSL.append(temp)



for in range(fontsBLS*4+fontsSLS,fontsBLS*4+fontsSLS+fontsRLS):
    fontsRL.append([myList[i],"aA",myList[i]])



for in range(fontsSLS):
    fontsBL.append(fontsSL[i])

temp= []
for in range(fontsRLS):
    temp.append(fontsRL[i])


for in range(5-fontsRLS):
    temp.append(emptyItem)   

fontsBL.append(temp

for in range(3-fontsSLS):
    fontsBL.append(emptyList)

fontsBLSfontsBLS+1

main_window.geometry('600x700+500+0'
main_window.configure(bg="#24252B")

toAdd=0
labels=[]
canvas = []
texts=[]

fonts = [["normal","roman"],["normal","italic"],["bold","roman"],["bold","italic"]]

for in range (4):
    labels.append([])
    canvas.append([])
    texts.append([])
    for in range (5):
        lab Label(main_window,text=fontsBL[i][j][2],width=10,wraplength=80,
                bg=bgColor,fg=fgColor)
        lab.grid(row=i*2,column=j)
        labels[i].append(lab)
        
        can Canvas(main_windowwidth=80height=80,
                        bg=bgColor)

        temp=[]
        theFont fontsBL[i][j][0]
        temp.appendcan.create_text(80/2-20,80/2-20,anchor=CENTER,text=fontsBL[i][j][1] ,font=(theFont,13,fonts[0][0],fonts[0][1]),fill="white"))
        temp.appendcan.create_text(80/2+20,80/2-20,anchor=CENTER,text=fontsBL[i][j][1] ,font=(theFont,13,fonts[1][0],fonts[1][1]),fill="#bd9b16"))
        temp.appendcan.create_text(80/2-20,80/2+20,anchor=CENTER,text=fontsBL[i][j][1],font=(theFont,13,fonts[2][0],fonts[2][1]),fill="white"))
        temp.appendcan.create_text(80/2+20,80/2+20,anchor=CENTER,text=fontsBL[i][j][1] ,font=(theFont,13,fonts[3][0],fonts[3][1]),fill="#bd9b16"))

        texts[i].append(temp)
        can.grid(row=i*2+1,column=j,padx=8,pady=8)
        canvas[i].append(can)

def updateFonts():
    global labels
    global canvas
    for in range (4):
        for in range (5):
            labels[i][j].configure(text=fontsBL[i+toAdd][j][2])
            can canvas[i][j]
            theFont fontsBL[i+toAdd][j][0]
            theTFFont fontsBL[i+toAdd][j][1]
            for in range(4):
                can.itemconfig(texts[i][j][k], text=theTFFont,
                                font=(theFont,13,fonts[k][0],fonts[k][1]))
   

def nextPage():
    global toAdd
    if toAdd<fontsBLS*4-4:
        toAdd=toAdd+4
        updateFonts()


def prevPage():
    global toAdd
    if toAdd>0:
        toAdd=toAdd-4
        updateFonts()     

def firstPage():
    global toAdd
    toAdd=0     
    updateFonts()   

def lastPage():
    global toAdd
    toAdd=fontsBLS*4-4    
    updateFonts()           

firstBut Button(main_window,text="First",bg="#bd9b16",
                 command=firstPage)
firstBut.grid(row=8,column=0,padx=8,pady=8,sticky=E)
lastBut Button(main_window,text="Last",bg="#bd9b16",
                 command=lastPage)
lastBut.grid(row=8,column=1,padx=8,pady=8,sticky=W)


prevBut Button(main_window,text="Previous",bg="#bd9b16",
                 command=prevPage)
prevBut.grid(row=8,column=4,padx=8,pady=8,sticky=E)
nextBut Button(main_window,text="Next",bg="#bd9b16",
                 command=nextPage)
nextBut.grid(row=8,column=5,padx=8,pady=8,sticky=E)


main_window.mainloop()

The Output

Something to say?

If you want to add something about this post, please feel free to do it by commenting below 🙂.