Hello World

We always need to follow two steps no matter how big the application is, there is always two steps. initialize the widget and shove it on the screen that it.

from tkinter import Tk,\
    Label
#initializing tkinter application
root = Tk()
# Creating label widget
myLabel = Label(root, text="Hello World!")
# Shoving it into the screen
myLabel.pack()
#start the application loop
root.mainloop()

Output:

Grid System

row: tells in which row to show

column: tells in which column to show

from tkinter import Tk,\
    Label

root = Tk()
# Creating label widget
myLabel1 = Label(root, text="Hello World!")
myLabel2 = Label(root, text="My name is Prince Billy Graham")
# Shoving it into the screen
myLabel1.grid(row=0, column=0) #grid
myLabel2.grid(row=0, column=1) #grid

root.mainloop()

Output:

Button

Here “fg” and “bg” supports only hex and text value. it does not support rgb values.

from tkinter import Tk, \
    Button,\
    Label

root = Tk()
def myClick():
    """Action for clicked button"""
    myLabel = Label(root, text="Look! I clicked a Button!!")
    myLabel.pack()
myButton = Button(root,
                  text="Click me",
                  # state="disabled", #disables button
                  padx=50,  #padding horizontal
                  pady = 20 #padding vertical
                  command=myClick, #onclick event 
                  fg="#fff",  #foreground color 
                  bg="#000"	  #background color
                  )
                  
myButton.pack()
root.mainloop()

Input fields

from tkinter import Tk, \
    Button, \
    Label, \
    Entry

root = Tk()

e = Entry( #input called as entry
    root,
    width=50,
    bg="blue",
    fg="white"
)
e.pack()
e.insert(0, "Enter your name") # placeholder


def my_click():
    """Action for clicked button"""
    my_label = Label(root, text="Hello, " + e.get()) #get the value in entry
    my_label.pack()


my_button = Button(root,
                   text="Click me",
                   # state="disabled",
                   padx=50,
                   command=my_click,
                   fg="#fff",
                   bg="#000"
                   )

my_button.pack()
root.mainloop()

Output:

A simple calculator app

from tkinter import Tk, \
    Button, \
    Entry

#global variables
first_number = 0
is_stack_empty = True
math = 'addition'

root = Tk()
root.title("Simple Calculator")  # set title of core window


e = Entry(
    root,
    borderwidth=5
)

e.grid(
    row=0,
    column=0,
    columnspan=3,
    padx=10,
    pady=10
)

e.insert(0, "0") # set 0 as placeholder from 0 postion of entry


def button_click(n):
    global is_stack_empty
    current = ''
    if is_stack_empty:
        is_stack_empty = False
    else:
        current = e.get()

    e.delete(0, "end")
    print(current)
    e.insert(0, current + str(n))


def clear_screen():
    """clear the screen"""
    e.delete(0, "end") # deletes entry value from 0 to end


def add():
    """saves first number to global variable"""
    global first_number
    global math
    math = "addition"
    first_number = int(e.get()) #gets entry value
    e.delete(0, "end")  # deletes entry value from 0 to end


def divide():
    """saves first number to global variable"""
    global first_number
    global math
    math = "division"
    first_number = int(e.get()) #gets the value of entry
    e.delete(0, "end") # deletes entry value from 0 to end


def multiply():
    """saves first number to global variable"""
    global first_number
    global math
    math = "multiplication"
    first_number = int(e.get())
    e.delete(0, "end") # deletes entry value from 0 to end


def subtract():
    """saves first number to global variable"""
    global first_number
    global math
    math = "subtraction"
    first_number = int(e.get())
    e.delete(0, "end") # deletes entry value from 0 to end


def evaluate():
    """shows the result of calculation"""
    global is_stack_empty
    second_number = int(e.get())
    e.delete(0, "end") # deletes entry value from 0 to end

    if math == "addition":
        result = first_number + second_number
    if math == "subtraction":
        result = first_number - second_number
    if math == "multiplication":
        result = first_number * second_number
    if math == "division":
        result = first_number / second_number

    e.insert(0, str(result))
    is_stack_empty = True


button_1 = Button(root, text='1', padx=40, pady=20, command=lambda: button_click(1))
button_2 = Button(root, text='2', padx=40, pady=20, command=lambda: button_click(2))
button_3 = Button(root, text='3', padx=40, pady=20, command=lambda: button_click(3))
button_4 = Button(root, text='4', padx=40, pady=20, command=lambda: button_click(4))
button_5 = Button(root, text='5', padx=40, pady=20, command=lambda: button_click(5))
button_6 = Button(root, text='6', padx=40, pady=20, command=lambda: button_click(6))
button_7 = Button(root, text='7', padx=40, pady=20, command=lambda: button_click(7))
button_8 = Button(root, text='8', padx=40, pady=20, command=lambda: button_click(8))
button_9 = Button(root, text='9', padx=40, pady=20, command=lambda: button_click(9))
button_0 = Button(root, text='0', padx=40, pady=20, command=lambda: button_click(0))

button_add = Button(root, text='+', padx=39, pady=20,
                    command=add)
button_equal = Button(root, text='=', padx=91, pady=20,
                      command=evaluate)
button_clear = Button(root, text='Clear', padx=79, pady=20,
                      command=clear_screen)

button_minus = Button(root, text='-', padx=42, pady=20,
                      command=subtract)
button_mult = Button(root, text='x', padx=42, pady=20,
                     command=multiply)
button_divide = Button(root, text='/', padx=45, pady=20,
                       command=divide)

button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)

button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)

button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)

button_0.grid(row=4, column=0)
button_clear.grid(row=4, column=1, columnspan=2)

button_add.grid(row=5, column=0)
button_equal.grid(row=5, column=1, columnspan=2)

button_minus.grid(row=6, column=0)
button_mult.grid(row=6, column=1)
button_divide.grid(row=6, column=2)

root.mainloop()

output:

Show images in tkinter

pip install Pillow
from tkinter import Tk, Label, Button, DISABLED, SUNKEN, E, W

from PIL import ImageTk, Image

root = Tk()
root.title("Simple Image Viewer by princebillygk")

images = [
    ImageTk.PhotoImage(Image.open('assets/img/pic_1.webp')),
    ImageTk.PhotoImage(Image.open('assets/img/pic_2.webp')),
    ImageTk.PhotoImage(Image.open('assets/img/pic_3.webp')),
    ImageTk.PhotoImage(Image.open('assets/img/pic_4.webp'))
]


class ImageViewer:
    """Image gallery widget"""

    def __init__(self, rootWidget):
        # init
        self.root = rootWidget
        self.my_label = Label(image=images[0])
        self.button_back = Button(rootWidget, text="<<", state=DISABLED)
        self.button_exit = Button(rootWidget, text="Exit Program", command=root.quit)
        self.button_forward = Button(rootWidget, text=">>", command=lambda: self.forward(1))
        self.status_bar = Label(rootWidget, text="1 of %d" % len(images), bd=1, relief=SUNKEN, anc=E)
        # render
        self.my_label.grid(row=0, column=0, columnspan=3)
        self.button_back.grid(row=1, column=0)
        self.button_exit.grid(row=1, column=1, pady=10)
        self.button_forward.grid(row=1, column=2)
        self.status_bar.grid(row=2, column=0, columnspan=3, sticky=W + E)

    def forward(self, index):
        """Go to next img"""
        # update
        self.my_label = Label(self.root, image=images[index])
        self.button_back = Button(self.root, text="<<", command=lambda: self.back(index - 1))
        if index >= 3:
            self.button_forward = Button(self.root, text=">>", state=DISABLED)
        else:
            self.button_forward = Button(self.root, text=">>", command=lambda: self.forward(index + 1))
        self.status_bar = Label(self.root, text="%d of %d" % (index + 1, len(images)), bd=1, relief=SUNKEN, anc=E)

        # re-render
        self.my_label.grid(row=0, column=0, columnspan=3)
        self.button_back.grid(row=1, column=0)
        self.button_forward.grid(row=1, column=2)
        self.status_bar.grid(row=2, column=0, columnspan=3, sticky=W + E)

    def back(self, index):
        """Go to previous img"""
        # update
        self.my_label = Label(self.root, image=images[index])
        if index <= 0:
            self.button_back = Button(self.root, text="<<", state="disabled")
        else:
            self.button_back = Button(self.root, text="<<", command=lambda: self.back(index - 1))
        self.button_forward = Button(self.root, text=">>", command=lambda: self.forward(index + 1))
        self.status_bar = Label(self.root, text="%d of %d" % (index + 1, len(images)), bd=1, relief=SUNKEN, anc=E)

        # re-render
        self.my_label.grid(row=0, column=0, columnspan=3)
        self.button_back.grid(row=1, column=0)
        self.button_forward.grid(row=1, column=2)
        self.status_bar.grid(row=2, column=0, columnspan=3, sticky=W + E)


imageViewer = ImageViewer(root)
root.mainloop()

Loads image

ImageTk.PhotoImage(Image.open('assets/img/pic_1.webp')

Loading Status bar

 self.status_bar = Label(self.root, text="%d of %d" % (index + 1, len(images)), bd=1, relief=SUNKEN, anc=E)
 # bd for border
 # relief = SUNKEN sunk the item into the screen
 # anc = E  Algn East
self.status_bar.grid(row=2, column=0, columnspan=3, sticky=W + E) 
 #stick=W + E streach width from West to East

Frame

Frames works as div (html)

we can either pack or grid in frame no matter what organization we have used in the parent widget of frame

from tkinter import Tk,Button, Frame

root = Tk()
root.title("Frame")

frame = Frame(root)
frame.pack(padx=10, pady=10)

button = Button(frame, text="Don't click here")
button.grid(row=0, column=0)
button1 = Button(frame, text="Click here")
button1.grid(row =0, column=1)
button2 = Button(root, text="Outside of frame")
button2.pack()

root.mainloop()

Using LabelFrame instead of Frame in the above example

- frame = Frame(root)
+ frame = LabelFrame(root, padx=5, pady=5)

Text above label frame
- frame = LabelFrame(root, padx=5, pady=5)
+ frame = LabelFrame(root, text="My Text" padx=5, pady=5)

Radio Button:

from tkinter import Tk, \
    StringVar, \
    Radiobutton, \
    Label, \
    Button

root = Tk()
root.title('Radio Button')

TOPPINGS = [
    ("Pepperoni", "pepproni"),
    ("Cheese", "cheese"),
    ("Mushroom", "mushroom"),
    ("Onion", "onion"),
    ("Chilly", "chilly"),
]

pizza = StringVar() # We need to work with tk variable when working with tk
#tk variable have some useful function like set and get
pizza.set('pepproni') #setting check box value

mybutton = Button(root,
                  text="Update",
                  command=lambda: clicked(pizza.get())
                  )
mybutton.pack()

my_label = Label(root, text=pizza.get())
my_label.pack()

for text, topping in TOPPINGS:
    Radiobutton(root, text=text, variable=pizza, value=topping, command=lambda: clicked(pizza.get())) \
        .pack()


def clicked(value):
    global my_label
    """Trigers action on radio button click"""
    my_label.forget()
    my_label = Label(root, text=value)
    my_label.pack()



root.mainloop()
\

Message Box

Showing different types of Message boxes

from tkinter import Tk, Button, messagebox

root = Tk()
root.title('Message Box')

def normal_popup():
    messagebox._show(
        "This is my popup",  # This will be show as title
        "Hello World"		 # This will be show as body
    )

def warning_popup():
    messagebox.showwarning(
        "This is warning popup",
        "Hei Hei, Are you in a hurry today!!!"
    )


def error_popup():
    messagebox.showerror(
        "This is warning popup",
        "Big error message"
    )


def info_popup():
    messagebox.showinfo(
        "This is Info popup",
        "Nice to meet you"
    )


Button(root,
       text="Open Normal popup",
       command=normal_popup).pack()

Button(root,
       text="Open Warning popup",
       command=warning_popup).pack()

Button(root,
       text="Open Normal popup",
       command=error_popup).pack()

Button(root,
       text="Open Info popup",
       command=info_popup).pack()

root.mainloop()

Asking different types of Question

from tkinter import Tk, Button, messagebox

root = Tk()
root.title('Message Box')


def askquestion():
    messagebox.askquestion("Question", "How are you?")


def yes_no():
    messagebox.askyesno("Yes or no", "Are you sure?")


def ok_cancel():
    messagebox.askokcancel("Ok?", "Is everything fine?")


def retry_cancel():
    messagebox.askretrycancel("Hei", "Wanna do it again?")


def yes_no_cancel():
    messagebox.askyesnocancel("Yes no cancel", "Do you want to save and close it?")


Button(root,
       text="Open question popup",
       command=askquestion).pack()

Button(root,
       text="Open yes or no or cancel question popup",
       command=yes_no_cancel).pack()

Button(root,
       text="Open yes or no question popup",
       command=yes_no).pack()

Button(root,
       text="Open ok or cancel popup",
       command=ok_cancel).pack()

Button(root,
       text="Open retry or cancel popup",
       command=retry_cancel).pack()

root.mainloop()

Interacting with messagebox

def yes_no():
    response = messagebox.askyesno("Yes or no", "Are you sure?")
    if response = 1
    	print("You clicked yes")
    else:
    	print("you clickd no")
Button(root,
       text="Open yes or no question popup",
       command=yes_no).pack()

Open new window in python

from tkinter import Tk, Label, Toplevel, Button

from PIL import ImageTk, Image

root = Tk()
root.title("Main Window")


class NewWindow(Toplevel):
    """Creates a new window over existing window"""
    def __init__(self, master):
        super().__init__(master)
        self.parent = master
        self.title('Secondary Window')
        self.my_img = ImageTk.PhotoImage(Image.open('pic_1.webp')) #we must keep this as extra reference other wise python will clear this value by garbage collector and the image will not be shown
        Label(self, image=self.my_img).pack()


def open_new_window():
    NewWindow(root)


Button(root, text="Open new window", command=open_new_window).pack()

root.mainloop()

File Dialogue

from pathlib import Path
from tkinter import Tk, filedialog, Label, Button

from PIL import ImageTk, Image

root = Tk()
root.title("File dialogue")


def insert_image():
    global img
    img_path = filedialog.askopenfile(
        initialdir=Path.home(),
        filetypes=(
            ("Image files", "*.png"), ("All Files", "*.*")))
    img = ImageTk.PhotoImage(Image.open(img_path.name))
    img_label = Label(image=img).pack()


Button(text="Insert Image", command=insert_image).pack()
root.mainloop()

Slider

from tkinter import Tk, Scale, HORIZONTAL, VERTICAL

root = Tk()
root.title("Slide")

horizontal = Scale(root,
                   orient=HORIZONTAL,
                   length=300,
                   from_=400,
                   to=600,
                   command=lambda x:
                   root.geometry(str(horizontal.get()) + "x" + str(vertical.get()))
                   )

vertical = Scale(root,
                 orient=VERTICAL,
                 length=300,
                 from_=400,
                 to=600,
                 command=lambda x:
                 root.geometry(str(horizontal.get()) + "x" + str(vertical.get()))
                 )

horizontal.pack()
vertical.pack()

root.mainloop()

Checkbox

The default offvalue is 0 and onvalue is 1 which is Intvar() but we can change it to any thing (eg. string)

from tkinter import Tk, Checkbutton, StringVar, Label

root = Tk()
root.title("Checkbox")


class CheckboxExample:
    """Creates a checkbox widget with label"""

    def __init__(self, master):
        self.value = StringVar()
        self.value.set("Not Checked")
        self.checkbox = Checkbutton(master,
                                    text="Check me or not",
                                    var=self.value,
                                    command=self.update_value,
                                    onvalue="Checked",
                                    offvalue="Not Checked")
        self.label = Label(text=self.value.get())
        self.checkbox.pack()
        self.label.pack()

    def update_value(self):
        self.label.forget()
        self.label = Label(text=self.value.get())
        self.label.pack()


CheckboxExample(root)
root.mainloop()

DropDown List

from tkinter import Tk, OptionMenu, StringVar, Label

root = Tk()
root.title('Drop Down Menu')

options = [
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday"
]


class DropDownExample:
    """Creates a example for dropdown menu"""

    def __init__(self, master):
        self.value = StringVar()
        self.value.set(options[0])
        self.dropdown = OptionMenu(master,
                                   self.value,
                                   *options,
                                   command=self.update_value)
        self.label = Label(text=self.value.get())
        self.dropdown.pack()
        self.label.pack()

    def update_value(self, value):
        self.label.forget()
        print(value)
        self.label = Label(text=value)
        self.label.pack()


dropdown = DropDownExample(root)
root.mainloop()