Welcome to our Python GUI Projects with Tkinter Article. Here we have a compilation of 5 Tkinter GUI Projects we made in Python on our CodersLegacy YouTube Channel. For those of you coming from the Channel, you can find the code here available for you to try for yourself.
For those of you seeing this for the first time, you can find the full explanations for the below code on our Channel, where we write it from scratch.
You can go check out our YouTube Channel with this link.
A Login Page
A simple login form that takes a username and password, and verifies whether it is correct using a file of passwords and usernames. For this program to work, you should have a file called Accounts.txt setup in the same directory.
Watch the Video!
Codefrom tkinter import *
from tkinter import messagebox
class Window:
def __init__(self, master):
self.master = master
self.Main = Frame(self.master)
self.L1 = Label(self.Main, text = "Welcome to our Login")
self.L1.grid(row = 0, column = 1, padx = 5, pady = 5, columnspan = 2)
# Username
self.L2 = Label(self.Main, text = "Username: ")
self.L2.grid(row = 1, column = 0, padx = 5, pady = 5)
self.E1 = Entry(self.Main, width = 30)
self.E1.grid(row = 1, column = 1, padx = 5, pady = 5, columnspan = 3)
# Password
self.L3 = Label(self.Main, text = "Password: ")
self.L3.grid(row = 2, column = 0, padx = 5, pady = 5)
self.E2 = Entry(self.Main, show = "*", width = 30)
self.E2.grid(row = 2, column = 1, padx = 5, pady = 5, columnspan = 3)
# Buttons
self.B1 = Button(self.Main, text = "Submit", command = self.verify)
self.B1.grid(row = 3, column = 2, padx = 5, pady = 5, sticky = "e")
self.B2 = Button(self.Main, text = "Clear", command = self.clear)
self.B2.grid(row = 3, column = 3, padx = 5, pady = 5)
self.Main.pack(padx = 5, pady = 5)
def clear(self):
self.E1.delete(0, 'end')
self.E2.delete(0, 'end')
def verify(self):
user = self.E1.get()
password = self.E2.get()
file = open("Accounts.txt", "r")
for line in file:
temp = line.strip("\n").split(",")
if user == temp[0] and password == temp[1]:
print("Your Login Credentials have been Verified")
return 1
prompt = messagebox.showerror(title = "Error!", message = "Incorrect Login Details")
return 0
root = Tk()
window = Window(root)
root.mainloop()
Sample Usernames and Passwords:
CodersLegacy,12345
John Hubbard,2020
Random,0000
Sarah,9009
Registration Form
A Registration form that takes input from the user using a variety of widgets placed in a rather interesting layout using the Pack Layout Manager. This data can then be saved to a MySQL database as permanent storage. For this program you need to have a MySQL database installed to use the data storage feature.
Watch the Video!
Codefrom tkinter import *
import mysql.connector
class Window():
def __init__(self, master):
self.master = master
self.Main = Frame(self.master)
# ----- Section 1
self.section1 = Frame(self.Main)
self.L1 = Label(self.section1, text = "First Name")
self.L1.pack(padx = 5, pady = 5, side = LEFT)
self.E1 = Entry(self.section1)
self.E1.pack(padx = 5, pady = 5, side = LEFT)
self.L2 = Label(self.section1, text = "Last Name")
self.L2.pack(padx = 5, pady = 5, side = LEFT)
self.E2 = Entry(self.section1)
self.E2.pack(padx = 5, pady = 5, side = LEFT)
self.section1.pack(padx = 5, pady = 5, expand = True, fill = X)
# ----- Section 1
# ----- Section 2
self.section2 = Frame(self.Main)
self.L3 = Label(self.section2, text = "Address")
self.L3.pack(padx = 5, pady = 5, side = LEFT)
self.E3 = Entry(self.section2, width = 30)
self.E3.pack(padx = 5, pady = 5, side = LEFT, expand = True, fill = X)
self.L4 = Label(self.section2, text = "Postal Code")
self.L4.pack(padx = 5, pady = 5, side = LEFT)
self.E4 = Entry(self.section2, width = 6)
self.E4.pack(padx = 5, pady = 5, side = LEFT)
self.section2.pack(padx = 5, pady = 5, expand = True, fill = X)
# ----- Section 2
# ----- Section 3
self.section3 = Frame(self.Main)
## ---- Section 3 sub-frame 1
self.section3_1 = Frame(self.section3)
self.L5 = Label(self.section3_1, text = "Pick your Gender")
self.L5.pack(padx = 5, pady = 5)
self.Rvar1 = IntVar()
self.R1 = Radiobutton(self.section3_1, text = "Male", variable = self.Rvar1, value = 1)
self.R1.pack(padx = 5, pady = 5)
self.R2 = Radiobutton(self.section3_1, text = "Female", variable = self.Rvar1, value = 2)
self.R2.pack(padx = 5, pady = 5)
self.R3 = Radiobutton(self.section3_1, text = "Other", variable = self.Rvar1, value = 3)
self.R3.pack(padx = 5, pady = 5)
self.section3_1.pack(padx = 50, pady = 5, side = LEFT)
## ---- Section 3 sub-frame 1
## ---- Section 3 sub-frame 2
self.section3_2 = Frame(self.section3)
self.L5 = Label(self.section3_2, text = "Pick an Option")
self.L5.pack(padx = 5, pady = 5)
self.Cvar1 = IntVar()
self.Cvar2 = IntVar()
self.Cvar3 = IntVar()
self.C1 = Checkbutton(self.section3_2, text = "Option1", variable = self.Cvar1)
self.C1.pack(padx = 5, pady = 5)
self.C2 = Checkbutton(self.section3_2, text = "Option2", variable = self.Cvar2)
self.C2.pack(padx = 5, pady = 5)
self.C3 = Checkbutton(self.section3_2, text = "Option3", variable = self.Cvar3)
self.C3.pack(padx = 5, pady = 5)
self.section3_2.pack(padx = 50, pady = 5, side = RIGHT)
## ---- Section 3 sub-frame 2
self.section3.pack(padx = 5, pady = 5, expand = True, fill = X)
# ----- Section 3
# ----- Section 4
self.section4 = Frame(self.Main)
self.L6 = Label(self.section4, text = "About yourself: ")
self.L6.pack(padx = 5, pady = 5)
self.T1 = Text(self.section4, height = 5, width = 30)
self.T1.pack(padx =5, pady = 5, expand = True, fill = X)
self.section4.pack(padx = 5, pady = 5, expand = True, fill = X)
# ----- Section 4
self.B0 = Button(self.Main, text = "Connect", command = self.connect)
self.B0.pack(padx = 5, pady = 5, side = LEFT)
self.B1 = Button(self.Main, text = "Create Table", command = self.create_table)
self.B1.pack(padx = 5, pady = 5, side = LEFT)
self.B2 = Button(self.Main, text = "Submit", command = self.submit)
self.B2.pack(padx = 5, pady = 5, side = RIGHT)
self.Main.pack(padx = 5, pady = 5, expand = True, fill = X)
def connect(self):
try:
self.db = mysql.connector.connect(
host = "localhost",
user = "root",
password = "shadow1963",
database = "data")
self.cursor = self.db.cursor()
print("Connection Succeeded")
except:
print("Connection Failed")
def create_table(self):
try:
self.cursor.execute("""CREATE TABLE regis_data
(firstname VARCHAR(30),
lastname VARCHAR(30),
address VARCHAR(100),
postal_code INT,
gender INT,
choice INT,
comments TEXT)""")
except:
print("Table already created")
def submit(self):
sql = """INSERT INTO regis_data (firstname, lastname, address, postal_code, gender, choice, comments)
VALUES (%s, %s, %s, %s, %s, %s, %s)"""
values = (self.E1.get(), self.E2.get(), self.E3.get(), self.E4.get(), str(self.Rvar1.get()),
str(self.Cvar1.get()) + str(self.Cvar2.get()) + str(self.Cvar3.get()), self.T1.get("1.0", "end"))
self.cursor.execute(sql, values)
self.db.commit()
root = Tk()
root.resizable(False, False)
window = Window(root)
root.mainloop()
Spreadsheet Program
This is a simple spreadsheet which has some basic features you might expect to see in a spreadsheet software. You can also save all the data in the spreadsheet into a file, and load it back into the spreadsheet at a later time.
Watch the Video!
Codefrom tkinter import *
class Window:
def __init__(self, master):
self.master = master
self.Main = Frame(self.master)
# TOP SECTION
self.top = Frame(self.Main)
self.title = Label(self.top, text = "Welcome to our SpreadSheet")
self.title.pack(padx = 5, pady = 5)
self.top.pack(padx = 5, pady = 5)
# TOP SECTION
# MIDDLE SECTION
self.middle = Frame(self.Main)
self.row = 10
self.col = 12
self.cells = [[None for i in range(self.col)] for j in range(self.row)]
for i in range(self.row):
for j in range(self.col):
self.cells[i][j] = Entry(self.middle, width = 5)
self.cells[i][j].grid(row = i, column = j)
self.middle.pack(padx = 5, pady = 5)
# MIDDLE SECTION
# BOTTOM SECTION
self.bottom = Frame(self.Main)
self.saveButton = Button(self.bottom, text = "Save", command = self.save)
self.saveButton.pack(padx = 5, pady = 5, side = RIGHT)
self.loadButton = Button(self.bottom, text = "Load", command = self.load)
self.loadButton.pack(padx = 5, pady = 5, side = RIGHT)
self.clearButton = Button(self.bottom, text = "Clear", command = self.clear)
self.clearButton.pack(padx = 5, pady = 5, side = LEFT)
self.bottom.pack(padx = 5, pady = 5, expand = True, fill = X)
# BOTTOM SECTION
self.Main.pack(padx = 5, pady = 5, expand = True, fill = X)
def save(self):
file = open("data.txt", "w")
for i in range(self.row):
for j in range(self.col):
file.write(self.cells[i][j].get() + ",")
file.write("\n")
file.close()
def load(self):
file = open("data.txt", "r")
self.clear()
for i in range(self.row):
temp = file.readline()
temp = temp.split(",")
for j in range(self.col):
self.cells[i][j].insert(0, temp[j].strip())
def clear(self):
for i in range(self.row):
for j in range(self.col):
self.cells[i][j].delete(0, 'end')
root = Tk()
window = Window(root)
root.mainloop()
Notepad Application
A simple Notepad application with the basic features found in Text Editors as well as the ability to Undo/Redo Actions.
Watch the Video!
Codefrom tkinter import *
from collections import deque
class Window:
def __init__(self, master):
self.master = master
self.Main = Frame(self.master)
self.stack = deque(maxlen = 10)
self.stackcursor = 0
self.L1 = Label(self.Main, text = "This is my NotePad")
self.L1.pack(padx = 5, pady = 5)
self.T1 = Text(self.Main, width = 80, height = 20)
self.T1.pack(padx = 5, pady = 5)
self.menu = Menu(self.Main)
self.menu.add_command(label = "Print", command = self.print_stack)
self.menu.add_command(label = "Undo", command = self.undo)
self.menu.add_command(label = "Redo", command = self.redo)
self.master.config(menu = self.menu)
self.B1 = Button(self.Main, text = "Print", width = 8, command = self.display)
self.B1.pack(padx = 5, pady = 5, side = LEFT)
self.B2 = Button(self.Main, text = "Clear", width = 8, command = self.clear)
self.B2.pack(padx = 5, pady = 5, side = LEFT)
self.B3 = Button(self.Main, text = "Undo", width = 8, command = self.undo)
self.B3.pack(padx = 5, pady = 5, side = LEFT)
self.B4 = Button(self.Main, text = "Redo", width = 8, command = self.redo)
self.B4.pack(padx = 5, pady = 5, side = LEFT)
self.Main.pack(padx = 5, pady = 5)
def display(self):
print(self.T1.get("1.0", "end"))
def clear(self):
self.T1.delete("1.0", "end")
def stackify(self):
self.stack.append(self.T1.get("1.0", "end - 1c"))
if self.stackcursor < 9: self.stackcursor += 1
def undo(self):
if self.stackcursor != 0:
self.clear()
if self.stackcursor > 0: self.stackcursor -= 1
self.T1.insert("0.0", self.stack[self.stackcursor])
def redo(self):
if len(self.stack) > self.stackcursor + 1:
self.clear()
if self.stackcursor < 9: self.stackcursor += 1
self.T1.insert("0.0", self.stack[self.stackcursor])
def print_stack(self):
i = 0
for stack in self.stack:
print(str(i) + " " + stack)
i += 1
root = Tk()
window = Window(root)
root.bind("<Key>", lambda event: window.stackify())
root.mainloop()
Syntax Highlighter + Code Editor
One of the more Complex GUI Projects with made with Python Tkinter. The Syntax Highlighter we made is here is rather crude, but it has many of the features you will find in simple Code Editors today such as Notepad++. It can color certain keywords, strings and important words, while also having automatic indenting to some extent.
Codefrom tkinter import *
from collections import deque
class Window:
def __init__(self, master):
self.master = master
self.master.option_add("*Font", "Verdana 12")
self.Main = Frame(self.master)
self.stack = deque(maxlen = 10)
self.stackcursor = 0
self.L1 = Label(self.Main, text = "This is my Code Editor")
self.L1.pack(padx = 5, pady = 5)
#---------
self.T1 = Text(self.Main, width = 90, height = 25)
self.T1.tag_configure("orange", foreground = "orange", font = "Verdana 12")
self.T1.tag_configure("blue", foreground = "blue", font = "Verdana 12")
self.T1.tag_configure("purple", foreground = "purple", font = "Verdana 12")
self.T1.tag_configure("green", foreground = "green", font = "Verdana 12")
self.T1.tag_configure("red", foreground = "red", font = "Verdana 12")
self.tags = ["orange", "blue", "purple", "green", "red"]
self.wordlist = [ ["class", "def", "for", "if", "else", "elif", "import", "from", "as", "break", "while"],
["int", "string", "float", "bool", "__init__"],
["pygame", "tkinter", "sys", "os", "mysql"],
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] ]
self.T1.bind("<Return>", lambda event: self.indent(event.widget))
self.T1.pack(padx = 5, pady = 5)
#---------
self.menu = Menu(self.Main)
self.menu.add_command(label = "Print", command = self.print_stack)
self.menu.add_command(label = "Undo", command = self.undo)
self.menu.add_command(label = "Redo", command = self.redo)
self.master.config(menu = self.menu)
self.B1 = Button(self.Main, text = "Print", width = 8, command = self.display)
self.B1.pack(padx = 5, pady = 5, side = LEFT)
self.B2 = Button(self.Main, text = "Clear", width = 8, command = self.clear)
self.B2.pack(padx = 5, pady = 5, side = LEFT)
self.B3 = Button(self.Main, text = "Undo", width = 8, command = self.undo)
self.B3.pack(padx = 5, pady = 5, side = LEFT)
self.B4 = Button(self.Main, text = "Redo", width = 8, command = self.redo)
self.B4.pack(padx = 5, pady = 5, side = LEFT)
self.Main.pack(padx = 5, pady = 5)
def tagHighlight(self):
start = "1.0"
end = "end"
for mylist in self.wordlist:
num = int(self.wordlist.index(mylist))
for word in mylist:
self.T1.mark_set("matchStart", start)
self.T1.mark_set("matchEnd", start)
self.T1.mark_set("SearchLimit", end)
mycount = IntVar()
while True:
index= self.T1.search(word,"matchEnd","SearchLimit", count=mycount, regexp = False)
if index == "": break
if mycount.get() == 0: break
self.T1.mark_set("matchStart", index)
self.T1.mark_set("matchEnd", "%s+%sc" % (index, mycount.get()))
preIndex = "%s-%sc" % (index, 1)
postIndex = "%s+%sc" % (index, mycount.get())
if self.check(index, preIndex, postIndex):
self.T1.tag_add(self.tags[num], "matchStart", "matchEnd")
def check(self, index, pre, post):
letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
if self.T1.get(pre) == self.T1.get(index):
pre = index
else:
if self.T1.get(pre) in letters:
return 0
if self.T1.get(post) in letters:
return 0
return 1
def scan(self):
start = "1.0"
end = "end"
mycount = IntVar()
regex_patterns = [r'".*"', r'#.*']
for pattern in regex_patterns:
self.T1.mark_set("start", start)
self.T1.mark_set("end", end)
num = int(regex_patterns.index(pattern))
while True:
index = self.T1.search(pattern, "start", "end", count=mycount, regexp = True)
if index == "": break
if (num == 1):
self.T1.tag_add(self.tags[4], index, index + " lineend")
elif (num == 0):
self.T1.tag_add(self.tags[3], index, "%s+%sc" % (index, mycount.get()))
self.T1.mark_set("start", "%s+%sc" % (index, mycount.get()))
def indent(self, widget):
index1 = widget.index("insert")
index2 = "%s-%sc" % (index1, 1)
prevIndex = widget.get(index2, index1)
prevIndentLine = widget.index(index1 + "linestart")
print("prevIndentLine ",prevIndentLine)
prevIndent = self.getIndex(prevIndentLine)
print("prevIndent ", prevIndent)
if prevIndex == ":":
widget.insert("insert", "\n" + " ")
widget.mark_set("insert", "insert + 1 line + 5char")
while widget.compare(prevIndent, ">", prevIndentLine):
widget.insert("insert", " ")
widget.mark_set("insert", "insert + 5 chars")
prevIndentLine += "+5c"
return "break"
elif prevIndent != prevIndentLine:
widget.insert("insert", "\n")
widget.mark_set("insert", "insert + 1 line")
while widget.compare(prevIndent, ">", prevIndentLine):
widget.insert("insert", " ")
widget.mark_set("insert", "insert + 5 chars")
prevIndentLine += "+5c"
return "break"
def getIndex(self, index):
while True:
if self.T1.get(index) == " ":
index = "%s+%sc" % (index, 1)
else:
return self.T1.index(index)
def update(self):
self.stackify()
self.tagHighlight()
self.scan()
def display(self):
print(self.T1.get("1.0", "end"))
def clear(self):
self.T1.delete("1.0", "end")
def stackify(self):
self.stack.append(self.T1.get("1.0", "end - 1c"))
if self.stackcursor < 9: self.stackcursor += 1
def undo(self):
if self.stackcursor != 0:
self.clear()
if self.stackcursor > 0: self.stackcursor -= 1
self.T1.insert("0.0", self.stack[self.stackcursor])
def redo(self):
if len(self.stack) > self.stackcursor + 1:
self.clear()
if self.stackcursor < 9: self.stackcursor += 1
self.T1.insert("0.0", self.stack[self.stackcursor])
def print_stack(self):
i = 0
for stack in self.stack:
print(str(i) + " " + stack)
i += 1
root = Tk()
window = Window(root)
root.bind("<Key>", lambda event: window.update())
root.mainloop()
This marks the end of the Python GUI Projects with Tkinter Article. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.