Ошибка с рекурсиями в Python

Хочу сделать программу тест про олимпийские игры но у меня возникла проблема. Я пытаюсь сделать чтобы по окончанию таймера был переход на следующий вопрос. Но возникает ошибка и таймер почти не идет назад либо не исчезает. Я сократил код до проблемных частей. Я пробовал return разными способами в виде функции, условных операторов.

Вот код:

from tkinter import messagebox
from _tkinter import *
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from platform import python_version
from datetime import datetime, time, timedelta



root = Tk()
root.geometry('1000x800')
root['bg'] = 'cyan4'
root.title('Quizop')


teamnamelbl = Label(root, bg='skyblue1', text='Введите название команды', font='Arial 18', width=43)
teamnameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
captainnamelbl = Label(root, bg='skyblue1', text='Введите капитана', font='Arial 18')
captainnameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
member2namelbl = Label(root, bg='skyblue1', text='Введите второго участника команды', font='Arial 18')
member2nameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
member3namelbl = Label(root, bg='skyblue1', text='Введите третьего участника команды', font='Arial 18')
member3nameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
member4namelbl = Label(root, bg='skyblue1', text='Введите четвертого участника команды', font='Arial 18')
member4nameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
member5namelbl = Label(root, bg='skyblue1', text='Введите пятого участника команды', font='Arial 18')
member5nameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')
member6namelbl = Label(root, bg='skyblue1', text='Введите шестого участника команды', font='Arial 18')
member6nameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')



vopr1var1lbl = Label(root, bg='skyblue1', text='Назовите родину олимпийских игр', font='Arial 18')
vopr1var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr1timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr2var1lbl = Label(root, bg='skyblue1', text='Кем были учреждены олимпийские игры?', font='Arial 18')
vopr2var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr2timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr3var1lbl = Label(root, bg='skyblue1', text='В честь какого бога устраивались олимпийские игры?', font='Arial 18')
vopr3var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr3timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr4var1lbl = Label(root, bg='skyblue1', text='Кто не мог участвовать в олимпийских играх в древности?', font='Arial 18')
vopr4var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr4timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr5var1lbl = Label(root, bg='skyblue1', text='В каком году состоялись первые олимпийские игры?', font='Arial 18')
vopr5var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr5timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr6var1lbl = Label(root, bg='skyblue1', text='В каком городе состоялись первые олимпийские игры?', font='Arial 18')
vopr6var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr6timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr7var1lbl = Label(root, bg='skyblue1', text='Участники соревнований в древности?', font='Arial 18')
vopr7var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr7timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr8var1lbl = Label(root, bg='skyblue1', text='Опишите 1-ый день соревнований.', font='Arial 18')
vopr8var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr8timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr9var1lbl = Label(root, bg='skyblue1', text='Опишите 2-ой день соревнований.', font='Arial 18')
vopr9var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr9timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr10var1lbl = Label(root, bg='skyblue1', text='Опишите 3-ий день соревнований.', font='Arial 18')
vopr10var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr10timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr11var1lbl = Label(root, bg='skyblue1', text='Опишите 4-ый день соревнований.', font='Arial 18')
vopr11var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr11timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr12var1lbl = Label(root, bg='skyblue1', text='Опишите 5-ый день соревнований.', font='Arial 18')
vopr12var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr12timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

vopr13var1lbl = Label(root, bg='skyblue1', text='Кто такой Милон?', font='Arial 18')
vopr13var1ent = Entry(root, bg='white', justify=CENTER, font='Arial 15', width=35)
vopr13timerlbl = Label(root, font=('calibri', 50, 'bold'), background='skyblue1', foreground='black')

finalrootlbl = Label(root, bg='skyblue1', text='Поздравляем! Вы завершили тест!', font='Arial 18')

format = '%H:%M:%S'

def startcommand():
    global teamnamestr
    teamnamestr = str(teamnameent.get())
    global captainnamestr
    captainnamestr = str(captainnameent.get())
    global member2namestr
    member2namestr = str(member2nameent.get())
    global member3namestr
    member3namestr = str(member3nameent.get())
    global member4namestr
    member4namestr = str(member4nameent.get())
    global member5namestr
    member5namestr = str(member5nameent.get())
    global member6namestr
    member6namestr = str(member6nameent.get())
    teamnamelbl.pack_forget()
    teamnameent.pack_forget()
    captainnamelbl.pack_forget()
    captainnameent.pack_forget()
    member2namelbl.pack_forget()
    member2nameent.pack_forget()
    member3namelbl.pack_forget()
    member3nameent.pack_forget()
    member4namelbl.pack_forget()
    member4nameent.pack_forget()
    member5namelbl.pack_forget()
    member5nameent.pack_forget()
    member6namelbl.pack_forget()
    member6nameent.pack_forget()
    startbtn.pack_forget()
    variant1btn.pack()

def vopr1var1btnfunc():
    variant1btn.pack_forget()
    vopr1var1lbl.pack()
    vopr1var1ent.pack()
    vopr1var1btn.pack()
    global currentvariant
    currentvariant = 'Задания для 5-6 классов'
    vopr1timerlbl.pack(anchor=CENTER)
    format1 = '%H:%M:%S'
    target1 = datetime.now() + timedelta(minutes=2)
    global update_time1
    def update_time1():
        now = datetime.now()
        if now < target1:
            remains = round((target1 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format1)
            vopr1timerlbl.config(text=text)
        else:
            vopr2var1()
        vopr1timerlbl.after(1000, update_time1)
    update_time1()
    
    


def vopr2var1btnfunc():
    if update_time1():
        return
    global vopr1var1answer
    vopr1var1answer = vopr1var1ent.get()
    vopr1var1lbl.pack_forget()
    vopr1var1ent.pack_forget()
    vopr1var1btn.pack_forget()
    vopr1timerlbl.pack_forget()
    vopr2var1lbl.pack()
    vopr2var1ent.pack()
    vopr2var1btn.pack()
    vopr2timerlbl.pack(anchor=CENTER)
    format2 = '%H:%M:%S'
    target2 = datetime.now() + timedelta(minutes=2)
    global update_time2
    def update_time2():
        now = datetime.now()
        if now < target2:
            remains = round((target2 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format2)
            vopr2timerlbl.config(text=text)
        else:
            vopr3var1()
        vopr2timerlbl.after(1000, update_time2)
    update_time2()


def vopr2var1():
    global vopr1var1answer
    vopr1var1answer = vopr1var1ent.get()
    vopr1var1lbl.pack_forget()
    vopr1var1ent.pack_forget()
    vopr1var1btn.pack_forget()
    vopr1timerlbl.pack_forget()
    vopr2var1lbl.pack()
    vopr2var1ent.pack()
    vopr2var1btn.pack()
    vopr2timerlbl.pack(anchor=CENTER)
    format2 = '%H:%M:%S'
    target2 = datetime.now() + timedelta(minutes=2)
    global update_time2
    def update_time2():
        now = datetime.now()
        if now < target2:
            remains = round((target2 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format2)
            vopr2timerlbl.config(text=text)
        else:
            vopr3var1()
        vopr2timerlbl.after(1000, update_time2)
    update_time2()
    
    
def vopr3var1btnfunc():
    if update_time2():
        return
    global vopr2var1answer
    vopr2var1answer = vopr2var1ent.get()
    vopr2var1lbl.pack_forget()
    vopr2var1ent.pack_forget()
    vopr2var1btn.pack_forget()
    vopr2timerlbl.pack_forget()
    vopr3var1lbl.pack()
    vopr3var1ent.pack()
    vopr3var1btn.pack()
    vopr3timerlbl.pack(anchor=CENTER)
    format3 = '%H:%M:%S'
    target3 = datetime.now() + timedelta(minutes=2)
    global update_time3
    def update_time3():
        now = datetime.now()
        if now < target3:
            remains = round((target3 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format3)
            vopr3timerlbl.config(text=text)
        else:
            vopr4var1()
        vopr3timerlbl.after(1000, update_time3)
    update_time3()
   

def vopr3var1():
    global vopr2var1answer
    vopr2var1answer = vopr2var1ent.get()
    vopr2var1lbl.pack_forget()
    vopr2var1ent.pack_forget()
    vopr2var1btn.pack_forget()
    vopr2timerlbl.pack_forget()
    vopr3var1lbl.pack()
    vopr3var1ent.pack()
    vopr3var1btn.pack()
    vopr3timerlbl.pack(anchor=CENTER)
    format3 = '%H:%M:%S'
    target3 = datetime.now() + timedelta(minutes=2)
    global update_time3
    def update_time3():
        now = datetime.now()
        if now < target3:
            remains = round((target3 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format3)
            vopr3timerlbl.config(text=text)
        else:
            vopr4var1()
        vopr3timerlbl.after(1000, update_time3)
    update_time3()
  
 

def vopr4var1btnfunc():
    if update_time3():
        return
    global vopr3var1answer
    vopr3var1answer = vopr3var1ent.get()
    vopr3var1lbl.pack_forget()
    vopr3var1ent.pack_forget()
    vopr3var1btn.pack_forget()
    vopr3timerlbl.pack_forget()
    vopr4var1lbl.pack()
    vopr4var1ent.pack()
    vopr4var1btn.pack()
    vopr4timerlbl.pack(anchor=CENTER)
    format4 = '%H:%M:%S'
    target4 = datetime.now() + timedelta(minutes=2)
    global update_time4
    def update_time4():
        now = datetime.now()
        if now < target4:
            remains = round((target4 - now).total_seconds())
            text = time(second=remains % 60, minute=remains // 60).strftime(format4)
            vopr4timerlbl.config(text=text)
        else:
            vopr5var1()
        vopr4timerlbl.after(1000, update_time4)
    update_time4()
root.mainloop()```

Ответы (1 шт):

Автор решения: Сергей

У вас основная ошибка - много почти одинакового кода. Внимание рассеивается. Много таймеров включающихся каждую секунду. Если вы придумаете еще с десяток вопросов, все превратиться в пизаньскую башню. Как только вы напишете больше двух почти одинаковых строк, сразу смотрите как это можно преобразовать в цикл, функцию или класс.

  1. Вы меняете в Label, фактически, только текст, так и меняйте текст а не метку. lbl['text'] = "новый вопрос"
  2. Все вопросы собирайте в кортежи, так вам легче будет по ним пробегаться, и легче, если что их заменять на другие.
  3. Используйте .after для таймеров и .after_cancel(id) для их отключения

Я написал заготовку с комментариями, для первой группы вопросов. Можете по подобию сделать рефакторинг вашего кода. И я думаю многое проясниться и упроститься.

from tkinter import *


team = ('Введите название команды', 'Введите капитана', 'Введите второго участника команды',
        'Введите третьего участника команды', 'Введите четвертого участника команды',
        'Введите пятого участника команды', 'Введите шестого участника команды')
i = 0


def question(lst):
    id_team = teamnamelbl.after(2000, question, lst)  # запускаем таймер, на 2 секунды (10000 - на 10 сек)
    global i
    if i < len(lst):
        teamnamelbl['text'] = lst[i]  # меняем вопрос
        i += 1
    else:
        teamnamelbl['text'] = ""  # очищаем метку
        i = 0
        teamnamelbl.after_cancel(id_team)  # останавливаем таймер


root = Tk()
root.geometry('1000x800')
root['bg'] = 'cyan4'
root.title('Quizop')

teamnamelbl = Label(root, bg='skyblue1', text="", font='Arial 18', width=43)
teamnameent = Entry(root, bg='white', justify=CENTER, width=47, font='Arial 18')

teamnamelbl.pack()
teamnameent.pack()

question(team)

root.mainloop()
→ Ссылка