Fonts can be given three ways, and the differences matter more than they look.
tk.Label(root, text="Hello", font=("Helvetica", 14, "bold")).pack()
Family, size, then optional styles from bold, italic, underline and overstrike. A positive size is in points, a negative size is in pixels, which is the reliable way to get the same result on screens with different scaling.
from tkinter import font
big = font.Font(family="Helvetica", size=14, weight="bold")
tk.Label(root, text="Hello", font=big).pack()
big.configure(size=20)
The advantage is live: change the object and every widget using it updates immediately. That is how you build a text size control in two lines.
default = font.nametofont("TkDefaultFont")
print(default.actual())
default.configure(size=12)
Tk defines a set of standard fonts that widgets use unless told otherwise: TkDefaultFont, TkTextFont, TkFixedFont, TkMenuFont, TkHeadingFont and a few more. Reconfiguring one changes the whole application at once, which is the neatest way to make everything a little bigger.
print(font.families())
Ask for a family that is not installed and Tk quietly substitutes another, so an application that looks right on your machine may not elsewhere. actual() tells you what you really got:
f = font.Font(family="Some Missing Face", size=12)
print(f.actual())
For anything that must look the same everywhere, use TkDefaultFont and TkFixedFont rather than naming a family.
f = font.Font(family="Helvetica", size=14)
print(f.measure("Hello"))
print(f.metrics("linespace"))
measure gives the width of a string in pixels, metrics gives ascent, descent and line spacing. Together they size a canvas or a window to fit its text, which is better than guessing and better than a fixed width that breaks on another machine.
tk.Tk(), or you get an error about no default root.Tkinter fonts and Pillow fonts are separate. Text drawn onto an image uses ImageFont.truetype with a path to a font file. See the ImageDraw module.