For my Python project, I wanted to make a crossword game GUI with SQL connectivity to display high scores. I tried to learn tkinter, but the only difficulty was that I cannot use classes or objects as they are not taught at my school yet. Still I managed to make a highly inefficient and ugly looking code (I am a newbie). Please suggest how to improve my code quality and writing style.
Here's my code:
# -*- coding: utf-8 -*-
import tkinter as tk
from PIL import ImageTk, Image
import mysql.connector
import requests
from io import BytesIO
#requesting password to access sql database
passwd = str(input("enter the password for sql database"))
#connecting to mysql
connection = mysql.connector.connect(host='localhost',
user='root',
password=passwd)
#creating database myschool
cursor = connection.cursor()
cursor.execute('''CREATE DATABASE IF NOT EXISTS myschool''')
cursor.execute('''USE myschool''')
#function to insert player score into database
def updatevalues(val1,val2,val3):
cursor = connection.cursor()
sql = "INSERT INTO crossword (User, timetaken, correctvalues) VALUES (%s, %s, %s)"
val = (val1,val2,val3)
cursor.execute(sql, val)
connection.commit()
#function to create table if crossword table doesnt not exist
def createtable():
cursor = connection.cursor()
cursor.execute('''CREATE TABLE crossword (User varchar(255),timetaken varchar(255),correctvalues int);''')
#defining delete and entry functions
def delete(entry):
entry.delete(0,'end')
return None
def entry_get(entry):
value1 = entry.get()
return value1
#defining a function to get the entered username
username = ''
def check():
global username
if entry_get(nameentry) :
username = str(entry_get(nameentry))
delete(nameentry)
new_window.destroy()
#making a login window
new_window = tk.Tk()
tk.Label(new_window,text='Enter username:',font=('Times New Roman',25)).place(x=80,y=100)
tk.Label(new_window,text='Welcome to My Game',font=('Algerian',35,'underline')).place(x=60,y=10)
tk.Label(new_window,text='Note: The Game will start as soon as you press enter',font=('Times New Roman',15)).place(x=70,y=230)
nameentry = tk.Entry(new_window)
nameentry.place(x=320,y=110,height=30,width=200)
sub1 = tk.Button(new_window,text="Enter", command = check)
sub1.place(x=250,y=160,height=40,width=150)
new_window.geometry('600x350')
new_window.mainloop()
#making the main crossword window
window = tk.Tk()
window.title("My GUI")
lab = tk.Label(window,text='Crossword#1')
#making a 30 min timer
def update_timeText():
if (state):
global timer
timer[2] += 1
if (timer[2] >= 100):
timer[2] = 0
timer[1] += 1
if (timer[1] >= 60):
timer[0] += 1
timer[1] = 0
timeString = pattern.format(timer[0], timer[1], timer[2])
timeText.configure(text=timeString)
if timer == [30,0,0]:
timeText.configure(text="30:00:00")
else:
window.after(10, update_timeText)
def start():
global state
state = True
def stop():
global state
state = False
state = False
timer = [0, 0, 0]
pattern = '{0:02d}:{1:02d}:{2:02d}'
timeText = tk.Label(window, text="00:00:00", font=("Helvetica", 30))
timeText.place(x=100,y=30)
update_timeText()
window.after(1,start)
#creating a canvas and making a crossword structure
cwidth=450
cheight=450
W = tk.Canvas(window,width=cwidth,height=cheight,highlightbackground='black')
W.place(x=100,y=100)
for i in range(0,450,50):
W.create_line(0,i,450,i)
W.create_line(i,0,i,450)
#marking numbers on grid
W.create_text(10,10,text=1)
W.create_text(110,10,text=2)
W.create_text(260,10,text=3)
W.create_text(310,10,text=4)
W.create_text(410,10,text=5)
W.create_text(10,110,text=6)
W.create_text(60,110,text=7)
W.create_text(160,110,text=8)
W.create_text(260,110,text=9)
W.create_text(360,110,text=10)
W.create_text(160,160,text=11)
W.create_text(10,210,text=12)
W.create_text(260,210,text=13)
W.create_text(160,260,text=14)
W.create_text(10,310,text=15)
W.create_text(110,310,text=16)
W.create_text(260,310,text=17)
W.create_text(310,310,text=18)
W.create_text(410,310,text=19)
W.create_text(10,410,text=20)
W.create_text(260,410,text=21)
#making black squares
W.create_rectangle(200,0,250,150,fill='black')
W.create_rectangle(150,50,300,100,fill='black')
W.create_rectangle(50,50,100,100,fill='black')
W.create_rectangle(350,50,400,100,fill='black')
W.create_rectangle(0,150,50,200,fill='black')
W.create_rectangle(100,150,150,200,fill='black')
W.create_rectangle(300,150,350,200,fill='black')
W.create_rectangle(400,150,451,200,fill='black')
W.create_rectangle(200,200,250,250,fill='black')
W.create_rectangle(0,250,50,300,fill='black')
W.create_rectangle(100,250,150,300,fill='black')
W.create_rectangle(300,250,350,300,fill='black')
W.create_rectangle(400,250,451,300,fill='black')
W.create_rectangle(200,300,250,451,fill='black')
W.create_rectangle(50,350,100,400,fill='black')
W.create_rectangle(150,350,300,400,fill='black')
W.create_rectangle(350,350,400,400,fill='black')
#creating section for clues
X = tk.Canvas(window,height=600,width=700,highlightbackground='black')
X.pack(padx=40,side='right')
#Across secion
X.create_text(130,50,font=('Arial',40),text='Across')
X.create_text(115,105,font=('Arial',20),text='1. Locale')
X.create_text(176,145,font=('Arial',20),text='3. Soup Containers')
X.create_text(180,185,font=('Arial',20),text='6. Nectar Gatherers')
X.create_text(150,225,font=('Arial',20),text='9. Fries or Slaw')
X.create_text(159,265,font=('Arial',20),text='11. Household pest')
X.create_text(167,305,font=('Arial',20),text='12. Belonging to Eda')
X.create_text(120,345,font=('Arial',20),text='13. __ of Evil')
X.create_text(150,385,font=('Arial',20),text='14. Morning Riser')
X.create_text(100,425,font=('Arial',20),text='15. Lazily')
X.create_text(138,465,font=('Arial',20),text='17. Buck or doe')
X.create_text(167,505,font=('Arial',20),text='20. Sunrise direction')
X.create_text(195,545,font=('Arial',19),text='21. you do this with a book')
#Down section
X.create_text(530,50,font=('Arial',40),text='Down')
X.create_text(520,105,font=('Arial',20),text='1. Long Sandwhich')
X.create_text(487,145,font=('Arial',20),text='2. Casual top')
X.create_text(471,185,font=('Arial',20),text='4. __ Baba')
X.create_text(471,225,font=('Arial',20),text='5. Observe')
X.create_text(484,265,font=('Arial',20),text='7. Concluded')
X.create_text(465,305,font=('Arial',20),text='8. Cheeky')
X.create_text(465,345,font=('Arial',20),text='9. Dont sit')
X.create_text(457,385,font=('Arial',20),text='10. Tee off')
X.create_text(516,425,font=('Arial',20),text='15. If__I said it once')
X.create_text(480,465,font=('Arial',20),text='16. __Angeles')
X.create_text(498,505,font=('Arial',20),text='18. New Years__')
X.create_text(530,545,font=('Arial',20),text='19. Scarlett or Maroon')
#linking tick image when answer is correct
img_url = "https://i.ibb.co/2PKKZrj/iconfinder-tick-16-22643.png"
response = requests.get(img_url)
img_data = response.content
img = ImageTk.PhotoImage(Image.open(BytesIO(img_data)))
def tickimg(x_co,y_co):
panel = tk.Label(window, image=img)
panel.place(x=x_co,y=y_co)
lis = [['1','A','site'],['1','D','sub'],['2','D','tee'],['3','A','cans'],['4','D','ali'],
['5','D','see'],['6','A','bees'],['7','D','ended'],['8','D','sassy'],
['9','A','side'],['9','D','stand'],['10','D','drive'],['11','A','ant'],['12','A','idas'],
['13','A','axis'],['14','A','sun'],['15','A','idly'],['15','D','ive'],
['16','D','los'],['17','A','deer'],['18','D','eve'],
['19','D','red'],['20','A','east'],['21','A','read']]
def listchange():
stop()
global timer
timestring = ''
minutes = timer[0]
if minutes < 10:
timestring += '0'+str(timer[0])+':'
else:
timestring += str(timer[0])+':'
seconds = timer[1]
if seconds < 10:
timestring += '0'+str(timer[1])+':'
else:
timestring += str(timer[1])+':'
milliseconds = timer[2]
if milliseconds < 10:
timestring += '0'+str(timer[2])
else:
timestring += str(timer[2])
return timestring
def button_fun():
global correct
global username
new_timer = listchange()
cursor = connection.cursor()
cursor.execute("""show tables;""")
if ('crossword',) in cursor:
updatevalues(username,new_timer,len(correct))
else:
createtable()
updatevalues(username,new_timer,len(correct))
def endscreen1():
root = tk.Tk()
def des():
root.destroy()
root.geometry('700x450')
tk.Label(root,text='THANK YOU',font=('Algerian',60)).place(x = 140,y = 30)
tk.Label(root,text='FOR',font=('Algerian',60)).place(x = 270, y = 120)
tk.Label(root,text='PLAYING',font=('Algerian',60)).place(x = 190, y= 210)
viewscore = tk.Button(root,text='VIEW HIGHSCORE',command=des)
viewscore.place(x=270,y=340,height=40,width=150)
root.mainloop()
def highscore():
newroot = tk.Tk()
newroot.geometry('800x700')
tk.Label(newroot,text='HIGH SCORES',font=('Algerian',50,'underline')).pack(side='top',pady=20)
Y = tk.Canvas(newroot,height=700,width=600,highlightbackground='black')
Y.pack(side='top',pady=30)
Y.create_line(200,0,200,700)
Y.create_line(400,0,400,700)
Y.create_text(100,30,text='Name',font=('Times New Roman',30))
Y.create_text(300,30,text='Time Taken',font=('Times New Roman',30))
Y.create_text(500,30,text='Correct',font=('Times New Roman',30))
Y.create_text(500,60,text='Answers',font=('Times New Roman',30))
Y.create_line(0,80,600,80)
cursor = connection.cursor()
cursor.execute('''select * from crossword order by correctvalues desc,timetaken ;''')
names = []
times = []
correct = []
for i in cursor:
names.append(i[0])
times.append(i[1])
correct.append(i[2])
x1_co = 100
x2_co = 300
x3_co = 500
y_co = 60
if len(names) > 8:
names = names[0:8]
for i in range(0,len(names)):
y_co += 50
Y.create_text(x1_co,y_co,text=names[i],font=('Times New Roman',20))
Y.create_text(x2_co,y_co,text=times[i],font=('Times New Roman',20))
Y.create_text(x3_co,y_co,text=correct[i],font=('Times New Roman',20))
newroot.mainloop()
correct = []
def check_func(myvav = False):
global correct
global isclicked
for i in range(len(lis)):
if entry_get(entry1) == lis[i][0] and entry_get(entry2) == lis[i][1] and entry_get(entry3) == lis[i][2]:
correct.append('1')
if i == 0:
tickimg(640,160)
W.create_text(25,25,font=('Times New Roman',25),text='S')
W.create_text(75,25,font=('Times New Roman',25),text='I')
W.create_text(125,25,font=('Times New Roman',25),text='T')
W.create_text(175,25,font=('Times New Roman',25),text='E')
if i == 1:
tickimg(980,160)
W.create_text(25,25,font=('Times New Roman',25),text='S')
W.create_text(25,75,font=('Times New Roman',25),text='U')
W.create_text(25,125,font=('Times New Roman',25),text='B')
if i == 2:
tickimg(980,200)
W.create_text(125,25,font=('Times New Roman',25),text='T')
W.create_text(125,75,font=('Times New Roman',25),text='E')
W.create_text(125,125,font=('Times New Roman',25),text='E')
if i == 3:
tickimg(640,200)
W.create_text(275,25,font=('Times New Roman',25),text='C')
W.create_text(325,25,font=('Times New Roman',25),text='A')
W.create_text(375,25,font=('Times New Roman',25),text='N')
W.create_text(425,25,font=('Times New Roman',25),text='S')
if i == 4:
tickimg(980,240)
W.create_text(325,25,font=('Times New Roman',25),text='A')
W.create_text(325,75,font=('Times New Roman',25),text='L')
W.create_text(325,125,font=('Times New Roman',25),text='I')
if i == 5:
tickimg(980,280)
W.create_text(425,25,font=('Times New Roman',25),text='S')
W.create_text(425,75,font=('Times New Roman',25),text='E')
W.create_text(425,125,font=('Times New Roman',25),text='E')
if i == 6:
tickimg(640,240)
W.create_text(25,125,font=('Times New Roman',25),text='B')
W.create_text(75,125,font=('Times New Roman',25),text='E')
W.create_text(125,125,font=('Times New Roman',25),text='E')
W.create_text(175,125,font=('Times New Roman',25),text='S')
if i == 7:
tickimg(980,320)
W.create_text(75,125,font=('Times New Roman',25),text='E')
W.create_text(75,175,font=('Times New Roman',25),text='N')
W.create_text(75,225,font=('Times New Roman',25),text='D')
W.create_text(75,275,font=('Times New Roman',25),text='E')
W.create_text(75,325,font=('Times New Roman',25),text='D')
if i == 8:
tickimg(980,360)
W.create_text(175,125,font=('Times New Roman',25),text='S')
W.create_text(175,175,font=('Times New Roman',25),text='A')
W.create_text(175,225,font=('Times New Roman',25),text='S')
W.create_text(175,275,font=('Times New Roman',25),text='S')
W.create_text(175,325,font=('Times New Roman',25),text='Y')
if i == 9:
tickimg(640,280)
W.create_text(275,125,font=('Times New Roman',25),text='S')
W.create_text(325,125,font=('Times New Roman',25),text='I')
W.create_text(375,125,font=('Times New Roman',25),text='D')
W.create_text(425,125,font=('Times New Roman',25),text='E')
if i == 10:
tickimg(980,400)
W.create_text(275,125,font=('Times New Roman',25),text='S')
W.create_text(275,175,font=('Times New Roman',25),text='T')
W.create_text(275,225,font=('Times New Roman',25),text='A')
W.create_text(275,275,font=('Times New Roman',25),text='N')
W.create_text(275,325,font=('Times New Roman',25),text='D')
if i == 11:
tickimg(980,440)
W.create_text(275,325,font=('Times New Roman',25),text='D')
W.create_text(375,175,font=('Times New Roman',25),text='R')
W.create_text(375,225,font=('Times New Roman',25),text='I')
W.create_text(375,275,font=('Times New Roman',25),text='V')
W.create_text(375,325,font=('Times New Roman',25),text='E')
if i == 12:
tickimg(625,320)
W.create_text(175,175,font=('Times New Roman',25),text='A')
W.create_text(225,175,font=('Times New Roman',25),text='N')
W.create_text(275,175,font=('Times New Roman',25),text='T')
if i == 13:
tickimg(627,360)
W.create_text(25,225,font=('Times New Roman',25),text='I')
W.create_text(75,225,font=('Times New Roman',25),text='D')
W.create_text(125,225,font=('Times New Roman',25),text='A')
W.create_text(175,225,font=('Times New Roman',25),text='S')
if i == 14:
tickimg(627,400)
W.create_text(275,225,font=('Times New Roman',25),text='A')
W.create_text(325,225,font=('Times New Roman',25),text='X')
W.create_text(375,225,font=('Times New Roman',25),text='I')
W.create_text(425,225,font=('Times New Roman',25),text='S')
if i == 15:
tickimg(627,440)
W.create_text(175,275,font=('Times New Roman',25),text='S')
W.create_text(225,275,font=('Times New Roman',25),text='U')
W.create_text(275,275,font=('Times New Roman',25),text='N')
if i == 16:
tickimg(627,480)
W.create_text(25,325,font=('Times New Roman',25),text='I')
W.create_text(75,325,font=('Times New Roman',25),text='D')
W.create_text(125,325,font=('Times New Roman',25),text='L')
W.create_text(175,325,font=('Times New Roman',25),text='Y')
if i == 17:
tickimg(980,480)
W.create_text(25,325,font=('Times New Roman',25),text='I')
W.create_text(25,375,font=('Times New Roman',25),text='V')
W.create_text(25,425,font=('Times New Roman',25),text='E')
if i == 18:
tickimg(980,520)
W.create_text(125,325,font=('Times New Roman',25),text='L')
W.create_text(125,375,font=('Times New Roman',25),text='O')
W.create_text(125,425,font=('Times New Roman',25),text='S')
if i == 19:
tickimg(627,520)
W.create_text(275,325,font=('Times New Roman',25),text='D')
W.create_text(325,325,font=('Times New Roman',25),text='E')
W.create_text(375,325,font=('Times New Roman',25),text='E')
W.create_text(425,325,font=('Times New Roman',25),text='R')
if i == 20:
tickimg(980,560)
W.create_text(325,325,font=('Times New Roman',25),text='E')
W.create_text(325,375,font=('Times New Roman',25),text='V')
W.create_text(325,425,font=('Times New Roman',25),text='E')
if i == 21:
tickimg(980,600)
W.create_text(425,325,font=('Times New Roman',25),text='R')
W.create_text(425,375,font=('Times New Roman',25),text='E')
W.create_text(425,425,font=('Times New Roman',25),text='D')
if i == 22:
tickimg(627,560)
W.create_text(25,425,font=('Times New Roman',25),text='E')
W.create_text(75,425,font=('Times New Roman',25),text='A')
W.create_text(125,425,font=('Times New Roman',25),text='S')
W.create_text(175,425,font=('Times New Roman',25),text='T')
if i == 23:
tickimg(627,600)
W.create_text(275,425,font=('Times New Roman',25),text='R')
W.create_text(325,425,font=('Times New Roman',25),text='E')
W.create_text(375,425,font=('Times New Roman',25),text='A')
W.create_text(425,425,font=('Times New Roman',25),text='D')
delete(entry1)
delete(entry2)
delete(entry3)
if myvav == True:
submitbutton.bind('<Button-1>',button_fun())
window.destroy()
endscreen1()
highscore()
if len(correct) == 24:
button_fun()
window.destroy()
endscreen1()
highscore()
#Entry windows ,check button and submit button
tk.Label(window,text='Number:',font=('Arial',15)).place(x=21,y=580)
entry1 = tk.Entry(window)
entry1.place(x=100,y=580,height=30,width=100)
tk.Label(window,text='A or D:',font=('Arial',15)).place(x=230,y=580)
entry2 = tk.Entry(window)
entry2.place(x=300,y=580,height=30,width=100)
tk.Label(window,text='Word:',font=('Arial',15)).place(x=437,y=580)
entry3 = tk.Entry(window)
entry3.place(x=500,y=580,height=30,width=100)
check_button = tk.Button(window,
text="Check",command=check_func)
check_button.place(x=270,y=630,height=30,width=100)
submitbutton = tk.Button(window,text="Submit",command=lambda: check_func(myvav=True))
submitbutton.place(x=500,y=630,height=30,width=100)
window.geometry("1366x768")
window.mainloop()
One more thing: I want to add data file handling in this, but I am not quite sure how that works. Any suggestions would be helpful.
W.create_textblocks? For example you could defineadd_across(627, 560, 25, 425, "EAST")oradd_down(980, 600, 425, 325, "RED"). As long as there are no answers, you may still improve your code. \$\endgroup\$