I'm currently finishing up a python programming bootcamp on Udemy, and I'm trying to make a typing speed test using tkinter. I think the issue I'm having is when I try to press the "start test" button, nothing seems to happen. I appreciate any input and thank you in advance!
I wanted to check my work so far to make sure what I'd put down was working, but when I tried running the program, nothing happened. The idea is once the user clicks the start button, a 'timer' starts counting down from 60, and a word from the word bank appears above the entry box; so far, when StartButton is clicked, nothing seems to happen in the window. Here's my code so far:
EDIT: The issue I'm having now is the correct_words variable only updates once when I check an answer; every other time, it just stays at 1. Also, the results pop-up shows correct_words still equalling 0 instead of the total number of correct entries.
import tkinter as tk
import random
wordbank = ['Lorem', 'ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.', 'Nam', 'vitae', 'interdum', 'purus.', 'Mauris', 'pharetra', 'volutpat', 'augue,', 'id', 'elementum', 'enim', 'auctor', 'eget.', 'Praesent', 'diam', 'nulla,', 'condimentum', 'eget', 'cursus', 'sed,', 'imperdiet', 'vitae', 'arcu.', 'Quisque', 'lacus', 'enim,', 'finibus', 'eu', 'dolor', 'sit', 'amet,', 'pretium', 'pulvinar', 'libero.', 'In', 'maximus', 'elementum', 'varius.', 'Praesent', 'est', 'dui,', 'ultricies', 'vel', 'facilisis', 'non,', 'imperdiet', 'eget', 'eros.', 'Class', 'aptent', 'taciti', 'sociosqu', 'ad', 'litora', 'torquent', 'per', 'conubia', 'nostra,', 'per', 'inceptos', 'himenaeos.', 'Nunc', 'in', 'odio', 'nec', 'massa', 'faucibus', 'rhoncus', 'non', 'eu', 'libero.', 'Suspendisse', 'aliquam', 'iaculis', 'tellus,', 'ut', 'malesuada', 'purus', 'elementum', 'id.', 'Cras', 'ipsum', 'est,', 'sollicitudin', 'eu', 'ipsum', 'vehicula,', 'condimentum', 'volutpat', 'enim.', 'Fusce', 'massa', 'ipsum,', 'tempus', 'vel', 'dictum', 'sit', 'amet,', 'pretium', 'ut', 'nisl.', 'Pellentesque', 'vitae', 'convallis', 'neque,', 'eu', 'posuere', 'arcu.', 'Aenean', 'tempor', 'mi', 'risus,', 'aliquet', 'porta', 'metus', 'condimentum', 'ut.', 'Sed', 'sagittis', 'justo', 'magna,', 'sit', 'amet', 'suscipit', 'sem', 'pulvinar', 'hendrerit.', 'Integer', 'vitae', 'viverra', 'dui.', 'Vestibulum', 'ante', 'ipsum', 'primis', 'in', 'faucibus', 'orci', 'luctus', 'et', 'ultrices', 'posuere', 'cubilia', 'curae;', 'Aenean', 'pretium', 'augue', 'in', 'purus', 'tincidunt,', 'a', 'ornare', 'ligula', 'bibendum.', 'Aenean', 'condimentum', 'turpis', 'id', 'libero', 'pellentesque', 'rutrum.', 'Aliquam', 'scelerisque', 'vitae', 'massa', 'et', 'porttitor.', 'Etiam', 'erat', 'ex,', 'semper', 'at', 'faucibus', 'in,', 'semper', 'nec', 'turpis.', 'Donec', 'vel', 'tincidunt', 'justo,', 'sodales', 'posuere', 'nibh.', 'Duis', 'porttitor', 'risus', 'accumsan,', 'semper', 'nibh', 'nec,', 'malesuada', 'magna.', 'Integer', 'massa', 'arcu,', 'tincidunt', 'ut', 'interdum', 'ut,', 'auctor', 'quis', 'risus.', 'Nulla', 'facilisi.', 'Morbi', 'eleifend', 'massa', 'erat,', 'id', 'vestibulum', 'odio', 'sagittis', 'eu.', 'Sed', 'rhoncus,', 'ante', 'id', 'sollicitudin', 'imperdiet,', 'risus', 'lacus', 'mattis', 'lorem,', 'ut', 'fermentum', 'mi', 'dui', 'sit', 'amet', 'diam.', 'Fusce', 'vulputate', 'bibendum', 'lacinia.', 'Curabitur', 'iaculis', 'ex', 'sed', 'lectus', 'auctor,', 'quis', 'dapibus', 'odio', 'euismod.', 'Fusce', 'convallis', 'maximus', 'placerat.', 'Curabitur', 'non', 'ullamcorper', 'ligula,', 'elementum', 'consectetur', 'odio.', 'Phasellus', 'suscipit', 'lorem', 'pulvinar', 'porta', 'tincidunt.', 'In', 'vel', 'metus', 'neque.', 'Integer', 'tincidunt', 'laoreet', 'pharetra.', 'Integer', 'volutpat', 'elit', 'at', 'sollicitudin', 'laoreet.', 'Ut', 'aliquam', 'semper', 'tristique.', 'Phasellus', 'pretium', 'nisi', 'imperdiet', 'nunc', 'ornare', 'dictum.', 'Nunc', 'iaculis,', 'dolor', 'nec', 'faucibus', 'interdum,', 'nunc', 'tellus', 'maximus', 'leo,', 'nec', 'mollis', 'felis', 'lectus', 'in', 'quam.', 'Duis', 'enim', 'augue,', 'vestibulum', 'quis', 'sagittis', 'vitae,', 'fringilla', 'cursus', 'enim.', 'Phasellus', 'volutpat,', 'ante', 'in', 'rutrum', 'lacinia,', 'leo', 'urna', 'ornare', 'sem,', 'non', 'dictum', 'nisl', 'libero', 'vitae', 'libero.', 'Aliquam', 'ac', 'est', 'sed', 'arcu', 'interdum', 'elementum.', 'Nullam', 'tincidunt,', 'dolor', 'sed', 'pharetra', 'facilisis,', 'sapien', 'nunc', 'ultricies', 'justo,', 'sed', 'maximus', 'purus', 'turpis', 'in', 'ante.', 'Vestibulum', 'non', 'erat', 'molestie,', 'tincidunt', 'lectus', 'non,', 'tempor', 'enim.', 'Mauris', 'ligula', 'leo,', 'volutpat', 'in', 'vestibulum', 'et,', 'porttitor', 'sit', 'amet', 'diam.', 'Sed', 'vel', 'justo', 'dolor.', 'Duis', 'nec', 'felis', 'placerat,', 'sollicitudin', 'felis', 'id,', 'eleifend', 'purus.', 'Cras', 'non', 'porta', 'tellus.', 'Cras', 'et', 'sapien', 'feugiat,', 'aliquet', 'nibh', 'ac,', 'molestie', 'ex.', 'Aenean', 'vitae', 'scelerisque', 'lectus.', 'Proin', 'pulvinar', 'mollis', 'nulla,', 'nec', 'luctus', 'lacus', 'dapibus', 'quis.', 'Phasellus', 'scelerisque', 'eros', 'a', 'neque', 'pharetra', 'cursus.', 'Quisque', 'urna', 'est,', 'consequat', 'sed', 'ipsum', 'ut,', 'consequat', 'malesuada', 'odio.', 'Nunc', 'posuere', 'leo', 'nec', 'lacus', 'malesuada', 'efficitur.', 'Ut', 'fermentum', 'tincidunt', 'felis', 'vitae', 'sollicitudin.', 'Curabitur', 'sed', 'neque', 'bibendum,', 'fringilla', 'orci', 'nec,', 'consectetur', 'mauris.', 'Phasellus', 'ultrices', 'semper', 'mauris,', 'ultrices', 'mattis', 'lectus.', 'Nunc', 'sit', 'amet', 'auctor', 'neque.', 'Morbi', 'sed', 'neque', 'maximus,', 'egestas', 'sapien', 'et,', 'congue', 'augue.', 'Morbi', 'lacus', 'orci,', 'tincidunt', 'a', 'diam', 'sit', 'amet,', 'finibus', 'scelerisque', 'nisl.', 'Aenean', 'egestas', 'luctus', 'diam,', 'sit', 'amet', 'iaculis', 'urna', 'tempus', 'id.']
window = tk.Tk()
window.title('Typing Speed Test!')
correct_words = 0
seconds = 60
test_word = tk.StringVar(value=random.choice(wordbank))
scoreboard = tk.Label(window, text=f'Correct Words: {correct_words}')
scoreboard.grid(row=0, column=0)
timeclock = tk.Label(window, text=f'Seconds: {seconds}')
timeclock.grid(row=1, column=0)
def results_popup(correct_words):
popup = tk.Toplevel(window)
popup.geometry("300x100")
popup.title("Results")
tk.Label(popup, text= f"{correct_words} words per minute!", font=('Mistral 18 bold')).place(x=150,y=80)
def run_test(seconds):
if seconds > 0:
timeclock.config(text=f'Seconds: {seconds}')
window.after(1000, lambda: run_test(seconds - 1))
else:
timeclock.config(text='Time\'s Up!')
results_popup()
def check_word(test_word, correct_words):
if TypeBox.get() == test_word.get():
correct_words += 1
scoreboard.config(text=f'Correct Words: {correct_words}')
test_word.set(random.choice(wordbank))
WordDisplay = tk.Label(window, textvariable=test_word)
WordDisplay.grid(row=2, column=0)
TypeBox = tk.Entry(window)
TypeBox.grid(row=3, column=0)
StartButton = tk.Button(window, text='Start Test! >:)', command=lambda: run_test(seconds))
StartButton.grid(row=2, column=1)
CheckAnswer = tk.Button(window, text='Check Answer!', command=lambda: check_word(test_word, correct_words))
CheckAnswer.grid(row=3, column=1)
window.mainloop()
There were two issues in your code first issue was that you are creating the variables too early which is causing RuntimeError: Too early to create variables
to avoid this error its a good practice to first create the tkinter window and then create variables.
The second error is that inside the run_test()
function you have a while loop which is taking seconds > 0
as a condition but seconds
is not defined inside the function. in-order to make seconds
variable accessible inside the function you can add seconds
as a positional argument for the run_test()
function.
This is an improved solution of the code you provided, if you observe I didn't use any for
or while
loop and neither the sleep()
function which cause the tkinter window to hang.
import tkinter as tk
import random
window = tk.Tk()
window.title('Typing Speed Test!')
wordbank = ['Lorem', 'ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.', 'Nam', 'vitae', 'interdum', 'purus.', 'Mauris', 'pharetra', 'volutpat', 'augue,', 'id', 'elementum', 'enim', 'auctor', 'eget.', 'Praesent', 'diam', 'nulla,', 'condimentum', 'eget', 'cursus', 'sed,', 'imperdiet', 'vitae', 'arcu.', 'Quisque', 'lacus', 'enim,', 'finibus', 'eu', 'dolor', 'sit', 'amet,', 'pretium', 'pulvinar', 'libero.', 'In', 'maximus', 'elementum', 'varius.', 'Praesent', 'est', 'dui,', 'ultricies', 'vel', 'facilisis', 'non,', 'imperdiet', 'eget', 'eros.']
correct_words = 0
seconds = 60
test_word = tk.StringVar(value=random.choice(wordbank))
scoreboard = tk.Label(window, text=f'Correct Words: {correct_words}')
scoreboard.grid(row=0, column=0)
timeclock = tk.Label(window, text=f'Seconds: {seconds}')
timeclock.grid(row=1, column=0)
def run_test(seconds):
if seconds >= 0:
timeclock.config(text=f'Seconds: {seconds}')
window.after(1000, lambda: run_test(seconds - 1))
else:
timeclock.config(text='Time\'s Up!')
def check_word(test_word, correct_words):
if TypeBox.get() == test_word.get():
correct_words += 1
scoreboard.config(text=f'Correct Words: {correct_words}')
WordDisplay.config(text='Correct!')
else:
WordDisplay.config(text='Try Again!')
test_word.set(random.choice(wordbank))
return correct_words
WordDisplay = tk.Label(window, textvariable=test_word)
WordDisplay.grid(row=2, column=0)
TypeBox = tk.Entry(window)
TypeBox.grid(row=3, column=0)
StartButton = tk.Button(window, text='Start Test! >:)', command=lambda: run_test(seconds))
StartButton.grid(row=2, column=1)
CheckAnswer = tk.Button(window, text='Check Answer!', command=lambda: update_score())
CheckAnswer.grid(row=3, column=1)
def update_score():
global correct_words
correct_words = check_word(test_word, correct_words)
window.mainloop()
Here's your code with fixed error:
import tkinter as tk
from tkinter import ttk, StringVar
import random
from time import *
window = tk.Tk()
window.title('Typing Speed Test!')
wordbank = ['Lorem', 'ipsum', 'dolor', 'sit', 'amet,', 'consectetur', 'adipiscing', 'elit.', 'Nam', 'vitae', 'interdum', 'purus.', 'Mauris', 'pharetra', 'volutpat', 'augue,', 'id', 'elementum', 'enim', 'auctor', 'eget.', 'Praesent', 'diam', 'nulla,', 'condimentum', 'eget', 'cursus', 'sed,', 'imperdiet', 'vitae', 'arcu.', 'Quisque', 'lacus', 'enim,', 'finibus', 'eu', 'dolor', 'sit', 'amet,', 'pretium', 'pulvinar', 'libero.', 'In', 'maximus', 'elementum', 'varius.', 'Praesent', 'est', 'dui,', 'ultricies', 'vel', 'facilisis', 'non,', 'imperdiet', 'eget', 'eros.']
correct_words = 0
seconds = 60
test_word = tk.StringVar(value=random.choice(wordbank))
scoreboard = tk.Label(window, text=f'Correct Words: {correct_words}')
scoreboard.grid(row=0, column=0)
timeclock = tk.Label(window, text=f'Seconds: {seconds}')
timeclock.grid(row=1, column=0)
def run_test(seconds):
while seconds > 0:
seconds -= 1
timeclock.configure(text=f'Seconds: {seconds}')
sleep(1)
window.update()
timeclock.text = 'Time\'s Up!'
window.update()
def check_word():
if TypeBox.get() == test_word:
correct_words += 1
else:
WordDisplay.text = 'Try Again!'
sleep(1)
test_word = random.choice(wordbank)
window.update()
WordDisplay = tk.Label(window, textvariable=test_word)
WordDisplay.grid(row=2, column=0)
TypeBox = tk.Entry(window, textvariable=StringVar)
TypeBox.grid(row=3, column=0)
StartButton = tk.Button(window, text='Start Test! >:)', command=lambda: run_test(seconds))
StartButton.grid(row=2, column=1)
CheckAnswer = tk.Button(window, text='Check Answer!', command=check_word)
CheckAnswer.grid(row=3, column=1)
window.mainloop()
Your code had many mistakes, try to upload a code that doesn't have this many errors.
Using for
or while
loop inside of tkinter window is not a good practice. Since, tkinter window keeps itself displaying by using a loop function called mainloop()
which repeatedly opens the window after it's closed, adding another loop inside the window causes discontinuity in the mainloop()
function.