Showing posts with label Tkinter. Show all posts
Showing posts with label Tkinter. Show all posts

Sunday, May 18, 2025

Tkinter Introduction - Top Widget, Method, Button

First, let's make shure that our tkinter module is working ok with simple for loop that will spawn 5 instances of blank Tk window

We will import all options from tkinter module because we are using only one module.

If using multiple modules, if we have some big scripts, we can use only specific methods from those modules. With that approach we are evading possible name clashes:


from tkinter import *

for x in range(5):
    Tk()

After using 3 lines from above, if you see all 5 windows on screen, all is ok with import.


Then we can proceed with import of messagebox, alias mb:

import tkinter.messagebox as mb

We need to initialize a blank window with this line:

top_win = Tk()

Then, geometry of a window is set o be 500 x 500:

top_win.geometry("500x500")

Function do_something() is needed to show msg box. Inside msg box, we will have mb activated targeting showinfo() method to show "lorem ipsum stuff" as Title in a window:

def do_something():
    mb.showinfo("Title", "lorem ipsum stuff")

 It's not enough just to have our custom function, we need to activate it on button. A name for button will be but_1. 

That button is located in top_win, and text inside it will be "Yeah". To connect button with function we are using command = do_something, without parenthesis:

but_1 = Button(top_win, text = "Yeah", command = do_something)

Of course, button but_1 must be positioned using coordinates x and y, using method place():

but_1.place(x = 2, y = 2)

Mainloop is needed at the bottom of script:

top_win.mainloop()

This is full script:

from tkinter import *
import tkinter.messagebox as mb

top_win = Tk()
top_win.geometry("500x500")

def do_something():
    mb.showinfo("Title", "lorem ipsum stuff")

but_1 = Button(top_win, text = "Yeah", command = do_something)
but_1.place(x = 2, y = 2)

top_win.mainloop()

Tuesday, April 22, 2025

Tkinter - Text Widget

In this tutorial we will talk about Tkinter Text Widget. Make sure that you can run this source, and than we will explain.

Please note, we are reading a textual file LICENCE.txt, which is located in Python install folder - this script must be in a folder where that txt file resides, too. You can set a path to some other txt file.

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

file = open("LICENSE.txt", "r")

t = Text(top_win, padx = 20, pady = 20, width = 50, height = 20,
         cursor = "dot", relief = RIDGE, bd = 10, bg = "lightyellow",
         fg = "red", selectbackground = "yellow", selectforeground = "black",
         font = "Verdana")

for x in file.read():
    t.insert(END, x)

file.close()
t.pack(side = TOP, anchor = NW)
top_win.mainloop()

This is line that will open LICENCE.txt for reading:

file = open("LICENSE.txt", "r")

And this is source for Text Widget. We have padding set, width and height set, type of cursor, type of relief, border width, background color, text color, font type is Verdana, and background and foreground color set when we select part of text:

t = Text(top_win, padx = 20, pady = 20, width = 50, height = 20,
         cursor = "dot", relief = RIDGE, bd = 10, bg = "lightyellow",
         fg = "red", selectbackground = "yellow", selectforeground = "black",
         font = "Verdana")

With for loop we are reading txt file content. Otherwise you will not see any text on screen, just borders and colors:

for x in file.read():
    t.insert(END, x)

This line will close file:

file.close()

As with other widgets we must pack our text section, and at the end of script is standard mainloop:

t.pack(side = TOP, anchor = NW)
top_win.mainloop()

Consider watching corresponding YouTube tutorial on Tkinter Text Widget.

This is end of this tutorial and YT playlist on Tkinter, and you have a lot of other Python tutorials on this site and WebDevPro channel.

Learn More:

Free Python Programming Course
Python Examples
Python How To
Python Modules 

YouTube WebDevPro Tutorials

Tkinter - Scrollbars

As with menu Tkinter widgets, we will need some explanations with Labels what specific widgets are used for:

lab_1 = Label(top_win, text ="Scrolls are Weird")
lab_1.pack(side = TOP, anchor = NW)

Scrollbars must be positioned inside some Tk window: 

scr_bar = Scrollbar(top_win)
scr_bar.pack(side = RIGHT, fill = Y)

Important - now we need Listbox with yscrollcommand that will target Scrollbar, in this case scr_bar:

items = Listbox(top_win, yscrollcommand = scr_bar.set)

If we are lazy to invent items, there is a for loop to populate a list:

for x in range(100):
    items.insert(END, "Item: " + str(x))

Now it's time to pack Listbox with items:

items.pack(side = LEFT, fill = BOTH)

Interesting thing with Scrollbars, they must be configured to target items, using this line:

scr_bar.config(command = items.yview)

This is full working source:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("200x200")

lab_1 = Label(top_win, text ="Scrolls are Weird")
lab_1.pack(side = TOP, anchor = NW)

scr_bar = Scrollbar(top_win)
scr_bar.pack(side = RIGHT, fill = Y)

items = Listbox(top_win, yscrollcommand = scr_bar.set)

for x in range(100):
    items.insert(END, "Item: " + str(x))

items.pack(side = LEFT, fill = BOTH)

scr_bar.config(command = items.yview)
top_win.mainloop()

Scrollbars are little bit weird, so definitely check YouTube tutorial on Scrollbars.

Tkinter - Scale

This source will produce simple Tkinter GUI with horizontal scale on it, in value range from 1 to 100, using label "Range". 

Scale will be packed to center of the top_win. At the bottom of the scale we will have submit Button. 

No functions at the moment, just GUI:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

scale = Scale(top_win, label = "Range", from_ = 1, to = 100,
              orient = HORIZONTAL)
scale.pack(anchor = CENTER)

btn_1 = Button(top_win, text = "Submit")
btn_1.pack(anchor = CENTER)

top_win.mainloop()

So, a source to create scale is this one:

scale = Scale(top_win, label = "Range", from_ = 1, to = 100,
              orient = HORIZONTAL)
scale.pack(anchor = CENTER)

What about a source with function that will print something on Python Shell based on values from Scale:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def select():
    selected = real_val.get()
    print("Selected From Range: ", selected)

    if selected >= 50:
        print("More Than 50")

real_val = IntVar()

scale = Scale(top_win, label = "Range", length = 200, from_ = 1, to = 100,
              orient = HORIZONTAL, troughcolor = "red", variable = real_val)
scale.pack(anchor = CENTER)

btn_1 = Button(top_win, text = "Submit", command = select)
btn_1.pack(anchor = CENTER)

top_win.mainloop()

Function select() will get and check a point from scale. That value will be printed in Python Shell.

Also, if value is higher than 50, that will be printed too.

def select():
    selected = real_val.get()
    print("Selected From Range: ", selected)

    if selected >= 50:
        print("More Than 50")

Value is stored in real_val using this line:

real_val = IntVar()

To connect scale with real_val, use these lines:

scale = Scale(top_win, label = "Range", length = 200, from_ = 1, to = 100,
              orient = HORIZONTAL, troughcolor = "red", variable = real_val)
scale.pack(anchor = CENTER)

At the end we need to connect a button with function, using "command = ":

btn_1 = Button(top_win, text = "Submit", command = select)
btn_1.pack(anchor = CENTER)

There is corresponding YouTube tutorial on Tkinter Scale.

Tkinter - Menubar and Menus

Time to talk about horizontal menubar. We will have options to ping Google and Yahoo, using os module.

Simple functions that will do pinging:

def pg():
    os.system("ping google.com")

def py():
    os.system("ping yahoo.com")

 Menu will be created in top_win:

bar = Menu(top_win)

Time to add buttons that will be connected to corresponding functions:

bar.add_command(label = "Ping Google", command = pg)
bar.add_command(label = "Ping Yahoo", command = py)

 But also we need to activate menu in top_win, before mainloop:

top_win.config(menu = bar)

This is full working source: 

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def pg():
    os.system("ping google.com")

def py():
    os.system("ping yahoo.com")

bar = Menu(top_win)

bar.add_command(label = "Ping Google", command = pg)
bar.add_command(label = "Ping Yahoo", command = py)

top_win.config(menu = bar)
top_win.mainloop()

We can also have menu which is found in most of the editors. Make sure that this source is working on your machine.

Once you run it, what is clicked will be printed in Python Shell. This is just a simple presentation how to connect buttons to vertical menus. In real life scenario our functions will be probably more advanced than printing stuff on screen.

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

bar = Menu(top_win)

def new():
    print("New Clicked")
def open_file():
    print("Open File Clicked")

file = Menu(bar)
file.add_command(label = "New", command = new)
file.add_command(label = "Open", command = open_file)
file.add_command(label = "Save")
file.add_command(label = "Save As")
file.add_command(label = "Close")
file.add_command(label = "Exit")

bar.add_cascade(label = "File", menu = file)

top_win.config(menu = bar)
top_win.mainloop()

There is also YouTube tutorial on how to create Menubar and Menus with Tkinter

Tkinter - Radiobuttons

Radiobuttons are easy, just as Checkbuttons. First, make sure that this simple source is working, and then we will explain:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

lab_1 = Label(top_win, text = "Select only one: ").pack(anchor = W)

real_stuff = IntVar()

rad_1 = Radiobutton(top_win, text = "Python", variable = real_stuff, value = 1)
rad_1.pack(anchor = W)

rad_2 = Radiobutton(top_win, text = "C++", variable = real_stuff, value = 2)
rad_2.pack(anchor = W)

rad_3 = Radiobutton(top_win, text = "Perl", variable = real_stuff, value = 3)
rad_3.pack(anchor = W)

top_win.mainloop()

To explain what needs to be done we will have Tkinter label:

lab_1 = Label(top_win, text = "Select only one: ").pack(anchor = W)

Place that will hold choice will be real_stuff:

real_stuff = IntVar()

Then we will have 3 radiobuttons, where all of them will point to real_stuff. Radio buttons will have dedicated value: 1, 2 and 3. This is important:

rad_1 = Radiobutton(top_win, text = "Python", variable = real_stuff, value = 1)
rad_1.pack(anchor = W)

rad_2 = Radiobutton(top_win, text = "C++", variable = real_stuff, value = 2)
rad_2.pack(anchor = W)

rad_3 = Radiobutton(top_win, text = "Perl", variable = real_stuff, value = 3)
rad_3.pack(anchor = W)

What about function that will process values ? Again, make sure that code works, and then we will explain: 

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def selected():
    selected = real_stuff.get()

    output.config(text = selected)

    if selected == 1:
        print("Selected: Python at position", selected)
    if selected == 2:
        print("Selected: C++ at position", selected)
    if selected == 3:
        print("Selected: Perl at position", selected)

lab_1 = Label(top_win, text = "Select only one: ").pack(anchor = W)

real_stuff = IntVar()

rad_1 = Radiobutton(top_win, text = "Python", variable = real_stuff,
                    value = 1, command = selected)
rad_1.pack(anchor = W)

rad_2 = Radiobutton(top_win, text = "C++", variable = real_stuff, value = 2,
                    command = selected)
rad_2.pack(anchor = W)

rad_3 = Radiobutton(top_win, text = "Perl", variable = real_stuff, value = 3,
                    command = selected)
rad_3.pack(anchor = W)

output = Label(top_win, text = "You Selected: ")
output.pack(anchor = W)

top_win.mainloop()

Function selected() will get values from real_stuff using get() method.

Then it will set what is captured as config text for output. Output is external Label where results will be printed, in Tkinter Window.

Also, based on choice, values will be printed in Python Shell using if checks: 

def selected():
    selected = real_stuff.get()

    output.config(text = selected)

    if selected == 1:
        print("Selected: Python at position", selected)
    if selected == 2:
        print("Selected: C++ at position", selected)
    if selected == 3:
        print("Selected: Perl at position", selected)

All radio buttons now have connection to function using "command = ":

rad_1 = Radiobutton(top_win, text = "Python", variable = real_stuff,
                    value = 1, command = selected)
rad_1.pack(anchor = W)

rad_2 = Radiobutton(top_win, text = "C++", variable = real_stuff, value = 2,
                    command = selected)
rad_2.pack(anchor = W)

rad_3 = Radiobutton(top_win, text = "Perl", variable = real_stuff, value = 3,
                    command = selected)
rad_3.pack(anchor = W)

And this is source for output Label:

output = Label(top_win, text = "You Selected: ")
output.pack(anchor = W)

As always, you have corresponding YT tutorial on Tkinter Radiobuttnos.

Tkinter - Checkbuttons

This tutorial will be about Tkinter Checkbuttons. First, make sure that you can run this code, and than we will explain it:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

gen_lab  = Label(top_win, text = "Engine Boost")
gen_lab.grid(row = 0, column = 0)

turbo_10 = IntVar()
turbo_20 = IntVar()

ch_10 = Checkbutton(top_win, text = "Boost +10", variable = turbo_10)
ch_10.grid(row = 1, column = 0)

ch_20 = Checkbutton(top_win, text = "Boost +20", variable = turbo_20)
ch_20.grid(row = 2, column = 0)

but_1 = Button(top_win, text = "Activate Boost")
but_1.grid(row = 3, column = 0)
top_win.mainloop()

Just as with Listbox Widget, we will need Labels for Checkbuttons:

gen_lab  = Label(top_win, text = "Engine Boost")
gen_lab.grid(row = 0, column = 0)

And than we will need 2 variables that will be used to hold values:

turbo_10 = IntVar()
turbo_20 = IntVar()

Now we need 2 Checkbuttons. Please note variable = that is connected to corresponding variables. Checkbuttons, as other Tkinter widgets must be positioned. In this case with grid option: 

ch_10 = Checkbutton(top_win, text = "Boost +10", variable = turbo_10)
ch_10.grid(row = 1, column = 0)

ch_20 = Checkbutton(top_win, text = "Boost +20", variable = turbo_20)
ch_20.grid(row = 2, column = 0)

And of course, submit button: 

but_1 = Button(top_win, text = "Activate Boost")
but_1.grid(row = 3, column = 0)

So far, so good.

Custom functions for Tkinter Checkbuttons

Make sure that you can run this code, and then we will explain it. You will see results in Python Shell:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def activate_boost():
    status_10 = turbo_10.get()
    status_20 = turbo_20.get()

    if status_10 == 1:
        print("Boost +10 Activated")
    if status_20 == 1:
        print("Boost +20 Activated")
    if status_10 == 1 and status_20 == 1:
        print("!" * 50)
        print("ALERT - DANGER")
        print("Lower Down Boost Levels - Just One Checkbutton")
    if status_10 == 0 and status_20 == 0:
        print("Normal Operation")

gen_lab  = Label(top_win, text = "Engine Boost")
gen_lab.grid(row = 0, column = 0)

turbo_10 = IntVar()
turbo_20 = IntVar()

ch_10 = Checkbutton(top_win, text = "Boost +10", variable = turbo_10)
ch_10.grid(row = 1, column = 0)

ch_20 = Checkbutton(top_win, text = "Boost +20", variable = turbo_20)
ch_20.grid(row = 2, column = 0)

but_1 = Button(top_win, text = "Activate Boost", command = activate_boost)
but_1.grid(row = 3, column = 0)
top_win.mainloop()

This is our custom function that will process what is checked:

def activate_boost():
    status_10 = turbo_10.get()
    status_20 = turbo_20.get()

    if status_10 == 1:
        print("Boost +10 Activated")
    if status_20 == 1:
        print("Boost +20 Activated")
    if status_10 == 1 and status_20 == 1:
        print("!" * 50)
        print("ALERT - DANGER")
        print("Lower Down Boost Levels - Just One Checkbutton")
    if status_10 == 0 and status_20 == 0:
        print("Normal Operation")

With status_10 and status_20 we will get choice. Then we are checking if only one status is set to 1, and printing appropriate text.

If both of statuses are 1, than we print a message: "Lower Down Boost Levels - Just One Checkbutton".

If both statuses are 0, which means they are not operational, than some imaginary machine is working in a normal mode, no any boost, and we are printing "Normal operation".

You are strongly advised to check corresponding YT tutorial on Checkbuttons.

Tkinter - Listbox

It's easy to create listboxes using Tkinter. In most cases having label for that list will be helpful, so let's create it and we will use grid option for positioning:

gen_lab = Label(top_win, text = "Domain")
gen_lab.grid(row = 0, column = 0)

Ok, now we will set Listbox that will deal with, for example, domain names. That listbox will be in top_win, as with all Tkinter widgets in most simple cases:

list_domains = Listbox(top_win)

Once we have it, we can populate a list with values using insert() method, stating item position in a list, and corresponding values:

list_domains.insert(1, "google.com")
list_domains.insert(2, "yahoo.com")
list_domains.insert(3, "bing.com")

Now it's the time to grid Listbox:

list_domains.grid(row = 1, column = 0)

And this is full working source with that simple list. No operations at the moment, but list is fine:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

gen_lab = Label(top_win, text = "Domain")
gen_lab.grid(row = 0, column = 0)

list_domains = Listbox(top_win)

list_domains.insert(1, "google.com")
list_domains.insert(2, "yahoo.com")
list_domains.insert(3, "bing.com")

list_domains.grid(row = 1, column = 0)
top_win.mainloop()

Now we will create function that will delete selected domain from a list. We are using curselection() method for item selection, and delete() method to remove selected item:

def delete_from_list():
    selected = list_domains.curselection()
    list_domains.delete(selected)

Function will be activated on button press:

but_1 = Button(top_win, text = "Delete From List", command = delete_from_list)
but_1.grid(row = 3, column = 0)

You are advised to check corresponding YT tutorial on Listbox:

This is full working script: 

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def delete_from_list():
    selected = list_domains.curselection()
    list_domains.delete(selected)

gen_lab = Label(top_win, text = "Domain")
gen_lab.grid(row = 0, column = 0)

list_domains = Listbox(top_win)

list_domains.insert(1, "google.com")
list_domains.insert(2, "yahoo.com")
list_domains.insert(3, "bing.com")

but_1 = Button(top_win, text = "Delete From List", command = delete_from_list)
but_1.grid(row = 3, column = 0)

list_domains.grid(row = 1, column = 0)
top_win.mainloop()


Tkinter - Frames

Think about Tkinter Frames as boxes that will help you to organize other Tkinter widgets. 

First, make sure that you can run this script on your system, and than we will analyze it:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

frm_1 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)
frm_2 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)

lab_name = Label(frm_1, text = "Name").grid(row = 0, column = 0)
lab_last_name = Label(frm_1, text = "LastName").grid(row = 1, column = 0)

ent_name = Entry(frm_1)
ent_name.grid(row = 0, column = 1)
ent_last_name = Entry(frm_1)
ent_last_name.grid(row = 1, column = 1)

but_1 = Button(frm_1, text = "Submit").grid(row = 3, column = 0)

lab_age = Label(frm_2, text = "Age").grid(row = 0, column = 0)
lab_pay = Label(frm_2, text = "Pay").grid(row = 1, column = 0)

ent_age = Entry(frm_2)
ent_age.grid(row = 0, column = 1)
ent_pay = Entry(frm_2)
ent_pay.grid(row = 1, column = 1)

but_2 = Button(frm_2, text = "Submit").grid(row = 3, column = 0)

frm_1.grid(row = 0, column = 0)
frm_2.grid(row = 0, column = 1)

top_win.mainloop()

Ok, to create Frame we must (as with other Tkinter widgets) place it into some window. In this case primary window will be top_win, with geometry 800 x 800.


To create a border around Frame we will say highlightthickness = 1, we can also set background color:

frm_1 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)
frm_2 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)

Then we will have Labels inside Frames:

lab_name = Label(frm_1, text = "Name").grid(row = 0, column = 0)
lab_last_name = Label(frm_1, text = "LastName").grid(row = 1, column = 0)

Having just labels is not enough, there's need for entry fields:

ent_name = Entry(frm_1)
ent_name.grid(row = 0, column = 1)
ent_last_name = Entry(frm_1)
ent_last_name.grid(row = 1, column = 1)

Submit button is also needed:

but_1 = Button(frm_1, text = "Submit").grid(row = 3, column = 0)

Now, what about Frame 2 where we will have another labels with corresponding fields:

lab_age = Label(frm_2, text = "Age").grid(row = 0, column = 0)
lab_pay = Label(frm_2, text = "Pay").grid(row = 1, column = 0)

And than entry fields for age and pay values:

ent_age = Entry(frm_2)
ent_age.grid(row = 0, column = 1)
ent_pay = Entry(frm_2)
ent_pay.grid(row = 1, column = 1)

Button in second frame will be positioned using grid values:

but_2 = Button(frm_2, text = "Submit").grid(row = 3, column = 0)

After all is done, there's time to position Frames using grid values:

frm_1.grid(row = 0, column = 0)
frm_2.grid(row = 0, column = 1)

Improved Tkinter Frame Script that will print data using Python Shell

First, make sure that you can run it:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")
def sub_nl():
    name = ent_name.get()
    last_name = ent_last_name.get()
    print("Name", name)
    print("LastName", last_name)
    print("-" * 79)

def sub_ap():
    age = ent_age.get()
    pay = ent_pay.get()
    print("Age: ", age)
    print("Pay: ", pay)
    print("-" * 79)

frm_1 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)
frm_2 = Frame(top_win, highlightbackground = "black", highlightthickness = 1)

lab_name = Label(frm_1, text = "Name").grid(row = 0, column = 0)
lab_last_name = Label(frm_1, text = "LastName").grid(row = 1, column = 0)

ent_name = Entry(frm_1)
ent_name.grid(row = 0, column = 1)
ent_last_name = Entry(frm_1)
ent_last_name.grid(row = 1, column = 1)

but_1 = Button(frm_1, text = "Submit", command = sub_nl).grid(row = 3, column = 0)

lab_age = Label(frm_2, text = "Age").grid(row = 0, column = 0)
lab_pay = Label(frm_2, text = "Pay").grid(row = 1, column = 0)

ent_age = Entry(frm_2)
ent_age.grid(row = 0, column = 1)
ent_pay = Entry(frm_2)
ent_pay.grid(row = 1, column = 1)

but_2 = Button(frm_2, text = "Submit", command = sub_ap).grid(row = 3, column = 0)

frm_1.grid(row = 0, column = 0)
frm_2.grid(row = 0, column = 1)

top_win.mainloop()

We will create function that will get data for a name and last name using get() method. After that function will just create simple Python Shell report:

def sub_nl():
    name = ent_name.get()
    last_name = ent_last_name.get()
    print("Name", name)
    print("LastName", last_name)
    print("-" * 79)

Another function will grab and print users age and pay values:

def sub_ap():
    age = ent_age.get()
    pay = ent_pay.get()
    print("Age: ", age)
    print("Pay: ", pay)
    print("-" * 79)

Now we will just upgrade a source for both buttons, connecting it with corresponding functions using "command = " option: 

but_1 = Button(frm_1, text = "Submit", command = sub_nl).grid(row = 3, column = 0)
but_2 = Button(frm_2, text = "Submit", command = sub_ap).grid(row = 3, column = 0)

If you don't understand those scripts give you some time and work with just one button.

There's also corresponding YT tutorial: Tkinter - Frames Explained

Tkinter - Get Value From Entry Fields

In this tutorial we will combine knowledge from previous scripts.

We have only one Label with corresponding Entry field. There is also submit button, but it's not yet connected to real function that will do processing. 

Place where we will see results will be inside dedicated Canvas. This is important to note.

Once we have that arrangement, we can continue with dedicated function that will do something.

So far, this is full working script:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")
        
lab_1 = Label(top_win, text = "Number", bg = "lightyellow")
lab_1.grid(row = 0, column = 0)

ent_1 = Entry(top_win)
ent_1.grid(row = 0, column = 1)

but_1 = Button(top_win, text = "Calculate", bg = "lightgreen")
but_1.grid(row = 1, column = 0)

c = Canvas(top_win, width = 100, heigh = 100, bg = "yellow")
c.grid(row = 2, column = 3)      

top_win.mainloop()

Ok, now it is the time to create function that will get values from entry field with get() method. Once we have data, we can do some simple calculations.

But we also need to have again Canvas to show results there using lab_2 label that deals with text values. This is whole source of function:

def calculate_func():
    number_atm = ent_1.get()
    print_res = (int(number_atm) * 2)

    c = Canvas(top_win, width = 100, heigh = 100, bg = "yellow")
    c.grid(row = 2, column = 3)

    lab_2 = Label(c)
    lab_2["text"] = print_res
    lab_2.grid(row = 1, column = 1)

Once we combine all needed a source, function, label, entry field, Canvases, this is full working script that will process and show results.

And yes, my best advice is to go through dedicated YT tutorial that covers Getting Values from Entry Field in Tkinter.

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

def calculate_func():
    number_atm = ent_1.get()
    print_res = (int(number_atm) * 2)

    c = Canvas(top_win, width = 100, heigh = 100, bg = "yellow")
    c.grid(row = 2, column = 3)

    lab_2 = Label(c)
    lab_2["text"] = print_res
    lab_2.grid(row = 1, column = 1)
        
lab_1 = Label(top_win, text = "Number", bg = "lightyellow")
lab_1.grid(row = 0, column = 0)

ent_1 = Entry(top_win)
ent_1.grid(row = 0, column = 1)

but_1 = Button(top_win, text = "Calculate", bg = "lightgreen", command = calculate_func)
but_1.grid(row = 1, column = 0)

c = Canvas(top_win, width = 100, heigh = 100, bg = "yellow")
c.grid(row = 2, column = 3)      

top_win.mainloop()

Tkinter - Labels and Entry Fields

In this tutorial we will learn how to have Entry fields in Tkitner Canvas. Users need explanations what to type in entry fields so we must create Labels.

First, we will create Canvas with lightgreen background. Position for Canvas is in top_win of size 800 x 800:

can = Canvas(top_win, width = 400, height = 400, bg = "lightgreen")  

 And than, Labels. We will position it using place() method:

user_name = Label(top_win, text = "Username: ")
user_name.place(x = 20, y = 40)

user_pass = Label(top_win, text = "Password: ")
user_pass.place(x = 20, y = 80)

Once we have Labels, it's time to create Entry fields. We also need to place them:

entry_name = Entry(top_win).place(x = 100, y = 40)

entry_pass = Entry(top_win).place(x = 100, y = 80)

After we are done with element positioning, it's time for Canvas using grid values:

can.grid(row = 0, column = 0)

This is full working source:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

can = Canvas(top_win, width = 400, height = 400, bg = "lightgreen")      

user_name = Label(top_win, text = "Username: ")
user_name.place(x = 20, y = 40)

user_pass = Label(top_win, text = "Password: ")
user_pass.place(x = 20, y = 80)

submit_buton = Button(top_win, text = "Login")
submit_buton.place(x = 20, y = 120)

entry_name = Entry(top_win).place(x = 100, y = 40)

entry_pass = Entry(top_win).place(x = 100, y = 80)

can.grid(row = 0, column = 0)
top_win.mainloop()

Tkinter - Line, Oval, Arc, Rectangle

In last tutorial we mentioned that Canvas will be place where we can have multiple shapes.

First, we will establish Canvas with width of 500 and height of 500, with lightgreen background:

area = Canvas(top_win, width = 500, height = 500, bg = "lightgreen")

Then, we will have an orange rectangle with starting coordinates 10 and 10, with ending coordinates in x = 200 and y = 200:

rec = area.create_rectangle(10, 10, 200, 200, fill = "orange")

Why not have another, yellow rectangle, just for fun:

rec_2 = area.create_rectangle(20, 20, 150, 150, fill = "yellow")

To create an arc we will have something like this:

arc = area.create_arc(30, 30, 300, 300, extent = 223, fill = "red")

What about an oval ? No problem, it's easy:

oval = area.create_oval(10, 10, 300, 50, fill = "yellow")

 It's not enough to have Canvas, we must Grid it. In this case in a cell defined by 0 0 , which means upper top corner:

area.grid(row = 0, column = 0)

Full working source code:  

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

area = Canvas(top_win, width = 500, height = 500, bg = "lightgreen")

rec = area.create_rectangle(10, 10, 200, 200, fill = "orange")
rec_2 = area.create_rectangle(20, 20, 150, 150, fill = "yellow")

arc = area.create_arc(30, 30, 300, 300, extent = 223, fill = "red")

oval = area.create_oval(10, 10, 300, 50, fill = "yellow")
    
area.grid(row = 0, column = 0)
top_win.mainloop()

Ok now we will have a bunch of lines. Their starting and ending coordinates will be randomly generated using random module. Don't forget to import it.

We will use for loop to generate lines:

for x in range(10):
    line = area.create_line(randrange(25, 100), randrange(25, 100),
                            randrange(50, 400), randrange(200, 400))

Full working script:

from tkinter import *
import tkinter.messagebox as mb
import os
from random import *

top_win = Tk()
top_win.geometry("800x800")

area = Canvas(top_win, width = 500, height = 500, bg = "lightgreen")

rec = area.create_rectangle(10, 10, 200, 200, fill = "orange")
rec_2 = area.create_rectangle(20, 20, 150, 150, fill = "yellow")

arc = area.create_arc(30, 30, 300, 300, extent = 223, fill = "red")

oval = area.create_oval(10, 10, 300, 50, fill = "yellow")

for x in range(10):
    line = area.create_line(randrange(25, 100), randrange(25, 100),
                            randrange(50, 400), randrange(200, 400))
    
area.grid(row = 0, column = 0)
top_win.mainloop()

Tkinter - Canvas

Think about Tkinter Canvas as a place where we can have other shapes. That means that we need coordinates and dimensions.

In this case we will have red shape, which will be in primary, top_win, with 800 x 800 dimensions. Width will be 200 and height will be 200. As with other Tkinter elements, it's not enough to have something, we must position it.

In this example, we will use Grids to position elements. Think about Grids as Excel cells. Those cells are determined by intersection of rows and columns:

shape = Canvas(top_win, width = 200, height = 200, bg = "red")
shape.grid(row = 0, column = 0)

Full script with 3 basic shapes, positioned by grid options will be like this:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

shape = Canvas(top_win, width = 200, height = 200, bg = "red")
shape.grid(row = 0, column = 0)

shape_2 = Canvas(top_win, width = 200, height = 200, bg = "orange")
shape_2.grid(row = 1, column = 1)

shape_3 = Canvas(top_win, width = 200, height = 200, bg = "orangered")
shape_3.grid(row = 2, column = 2)

top_win.mainloop()

Also, we can have Canvases positioned by packing. In that case we need to think about sides and anchoring:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

shape = Canvas(top_win, width = 200, height = 200, bg = "red")
shape.pack(side = TOP, anchor = NW)

shape_2 = Canvas(top_win, width = 200, height = 200, bg = "orange")
shape_2.pack(side = RIGHT, anchor = NE)

shape_3 = Canvas(top_win, width = 200, height = 200, bg = "orangered")
shape_3.pack(side = BOTTOM, anchor = SW)

top_win.mainloop()

Another option is to experiment with pixels. Placing Canvases py pixels demands in most cases a little bit more time, but at the end of the day we can be happy with precision:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("800x800")

shape = Canvas(top_win, width = 200, height = 200, bg = "red")
shape.place(x = 100, y = 100)

shape_2 = Canvas(top_win, width = 200, height = 200, bg = "orange")
shape_2.place(x = 150, y = 150)

shape_3 = Canvas(top_win, width = 200, height = 200, bg = "orangered")
shape_3.place(x = 300, y = 300)

top_win.mainloop()

Monday, April 21, 2025

Tkinter Toplevel - New Window Spawn

Ok, now it's time to pay attention. We will spawn a new window in our Tkinter app by clicking on button.

To do that we will need dedicated function. Just as with a primary window, for spawned window we need to set geometry, which in most cases will be smaller than for a primary app. In this case, 300 x 300.

In that new function we will have independent button that will call some normal function, like to ping Google, or something simple like that.

As with any button, we need to pack it. At the end of net_window() function we will have mainloop:

def net_window():
    net_win = Toplevel()
    net_win.geometry("300x300")

    but_google = Button(net_win, text = "Ping Google", command = ping_google)
    but_google.pack(side = LEFT, anchor = NW)

    net_win.mainloop()

Our normal function (that is doing some useful operation) will just ping Google:

def ping_google():
    os.system("ping google.com")

Now we need to have primary button but_prim that will spawn new app window:

but_prim = Button(top_win, text = "Net Window", command = net_window)
but_prim.pack(side = LEFT, anchor = NW)

You are advised to check corresponding YT tutorial on How to Spawn New Window in Tkinter.

This is full working script:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def net_window():
    net_win = Toplevel()
    net_win.geometry("300x300")

    but_google = Button(net_win, text = "Ping Google", command = ping_google)
    but_google.pack(side = LEFT, anchor = NW)

    net_win.mainloop()

def ping_google():
    os.system("ping google.com")

but_prim = Button(top_win, text = "Net Window", command = net_window)
but_prim.pack(side = LEFT, anchor = NW)

top_win.mainloop()

If you don't understand a previous tutorial, give yourself some time. There is no purpose in code memorization, just try to understand an approach. Perhaps code before looks a little bit complicated, bit in fact it is not.

A little bit bigger example

In this example we are improving previous code in such ways that we can have one more button that will spawn new window, and in that window we will have some normal function which will run Notepad. Function to spawn new Notepad window will be this one:

def notepad_window():
    note_window = Toplevel()
    note_window.geometry("300x300")

    but_note = Button(note_window, text = "Notepad", command = run_notepad)
    but_note.pack(side = LEFT, anchor = NW)

    note_window.mainloop()

Function that will run Notepad is this, simple one:

def run_notepad():
    os.system("notepad")

Now, button that will spawn Window where is button to run Notepad is this one:

but_prim_notepad = Button(top_win, text = "Run Notepad", command = notepad_window)
but_prim_notepad.pack(side = LEFT, anchor = NW)

Again as before you are advised to check corresponding YT tutorial on How to Spawn New Window in Tkinter.

This is full working script:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def net_window():
    net_win = Toplevel()
    net_win.geometry("300x300")

    but_google = Button(net_win, text = "Ping Google", command = ping_google)
    but_google.pack(side = LEFT, anchor = NW)

    net_win.mainloop()

def notepad_window():
    note_window = Toplevel()
    note_window.geometry("300x300")

    but_note = Button(note_window, text = "Notepad", command = run_notepad)
    but_note.pack(side = LEFT, anchor = NW)

    note_window.mainloop()
    

def ping_google():
    os.system("ping google.com")

def run_notepad():
    os.system("notepad")

but_prim = Button(top_win, text = "Net Window", command = net_window)
but_prim.pack(side = LEFT, anchor = NW)

but_prim_notepad = Button(top_win, text = "Run Notepad", command = notepad_window)
but_prim_notepad.pack(side = LEFT, anchor = NW)

top_win.mainloop()

Tkinter Buttons - Background Image, Relief, Anchor

Tkinter Button Background Image

Yes, we can set real image as background for a button. This time we are using but_2_img that will point to bg-img.gif.

Please note image extension, it must be .gif format:

but_2_img = PhotoImage(file = "bg-img.gif")

 After .gif image is ready and set, we can connect it to button but_2. It's important to have command compound="c":

but_2 = Button(top_win, text="Calc", image = but_2_img, width = 100, height = 100,
               fg = "white", font = ("Arial", 16), compound = "c", command = run_calc)

You are highly advised to watch corresponding YT tutorial that covers this topic.

Other things you know from previous tutorials, so this is our full working script:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def run_calc():
    os.system("calc")


but_2_img = PhotoImage(file = "bg-img.gif")
but_2 = Button(top_win, text="Calc", image = but_2_img, width = 100, height = 100,
               fg = "white", font = ("Arial", 16), compound = "c", command = run_calc)
but_2.place(x = 0, y = 0)

top_win.mainloop()

Tkinter Button Packing

If you don't like messing around with pixels for placing buttons somewhere on app windows, we can use pack() method. 

In that case horizontally we can use values LEFT, RIGHT, TOP, BOTTOMDo not use quotes around those uppercase values. 

Also, we will anchor buttons using values like "N", "NE", "E", "SE", "S", "SW", "W", "NW", and also "CENTER". Anchor values are points of the compass:

but_3 = Button(top_win, text="Notepad", command = run_notepad)
but_3.pack(side = LEFT, anchor = NW)

but_4 = Button(top_win, text="Notepad", command = run_notepad)
but_4.pack(side = LEFT, anchor = NW)

Full script: 

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def run_notepad():
    os.system("notepad")
    
but_3 = Button(top_win, text="Notepad", command = run_notepad)
but_3.pack(side = LEFT, anchor = NW)

but_4 = Button(top_win, text="Notepad", command = run_notepad)
but_4.pack(side = LEFT, anchor = NW)

top_win.mainloop()

Tkinter Button Relief

It's easy to set Relief for buttons. Just use relief uppercase values, without quotes: RAISED, FLAT, SUNKEN, GROOVE or RIDGE:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def run_notepad():
    os.system("notepad")
    
but_3 = Button(top_win, text="Notepad", relief = FLAT, command = run_notepad)
but_3.pack(side = LEFT, anchor = NW)

but_4 = Button(top_win, text="Notepad", relief = SUNKEN, command = run_notepad)
but_4.pack(side = LEFT, anchor = NW)

top_win.mainloop()


Tkinter Buttons - Size, Colors, Font

We can play a lot with buttons. Not just with coordinates, but with size, colors and font types:

Interesting thing, to activate all those additional options we need to have blank button with PhotoImage() where width and height must be set:

common_img = PhotoImage(width = 1, height = 1)

For simplicity reasons we will play with one button but_1. There is some things here that must be done.

One of them is set image = common_img.

Width is set to 100 and height to 20.

Background color is defined with bg="lightgreen".

Foreground color is set with fg = "red".

Those colors are static. Once you press button, color can be different.

To set button background while it is pressed we will say activebackground = "white".

An active foreground is set with activeforeground = "orange".

For a font we will use System type, with font = ("System").

Don't forget to connect command= with function run_ping()

Until now our code for a button is this:

common_img = PhotoImage(width = 1, height = 1)

but_1 = Button(top_win, text="Ping Google", image = common_img,
               width = 100, height = 20,
               compound = "c", bg = "lightgreen", fg = "red",
               activebackground = "white", activeforeground = "orange",
               font = ("System"), command = run_ping)

Of course we need button position and mainloop, but we know that from previous tutorials.

This is full working source:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def run_ping():
    os.system("ping google.com")

common_img = PhotoImage(width = 1, height = 1)

but_1 = Button(top_win, text="Ping Google", image = common_img,
               width = 100, height = 20,
               compound = "c", bg = "lightgreen", fg = "red",
               activebackground = "white", activeforeground = "orange",
               font = ("System"), command = run_ping)
but_1.place(x = 5, y = 5)

top_win.mainloop()


Tkinter Buttons - Run External Apps from Tkinter

So far soo good. Now we will import os module to have access to system commands:

from tkinter import *
import tkinter.messagebox as mb
import os

 Again we need a main window and geometry:

top_win = Tk()
top_win.geometry("500x500")

Now we are creating 3 independent functions.

First function will ping google.com, or any other domain you like: 

def run_ping():
    os.system("ping google.com")

Second function will run Windows Calculator:

def run_calc():
    os.system("calc")

Third function will run Notepad:

def run_notepad():
    os.system("notepad")

All those functions must have corresponding buttons. Don't forget to set command= to appropriate functions we created. 

Also, for every button we must position it using x and y coordinates. You can experiment with pixel values, those I have in source code works for me:

but_1 = Button(top_win, text = "Ping Google", command = run_ping)
but_1.place(x = 5, y = 5)

but_2 = Button(top_win, text = "Calc", command = run_calc)
but_2.place(x = 82, y = 5)

but_3 = Button(top_win, text = "Notepad", command = run_notepad)
but_3.place(x = 118, y = 5)

Don't forget mainloop at the end of code:

top_win.mainloop()

This is full working script:

from tkinter import *
import tkinter.messagebox as mb
import os

top_win = Tk()
top_win.geometry("500x500")

def run_ping():
    os.system("ping google.com")

def run_calc():
    os.system("calc")

def run_notepad():
    os.system("notepad")
    

but_1 = Button(top_win, text = "Ping Google", command = run_ping)
but_1.place(x = 5, y = 5)

but_2 = Button(top_win, text = "Calc", command = run_calc)
but_2.place(x = 82, y = 5)

but_3 = Button(top_win, text = "Notepad", command = run_notepad)
but_3.place(x = 118, y = 5)

top_win.mainloop()


Tkinter Introduction - Top Widget, Method, Button

First, let's make shure that our tkinter module is working ok with simple  for loop that will spawn 5 instances of blank Tk window .  ...