Ошибка с рекурсиями в 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 шт):
У вас основная ошибка - много почти одинакового кода. Внимание рассеивается. Много таймеров включающихся каждую секунду. Если вы придумаете еще с десяток вопросов, все превратиться в пизаньскую башню. Как только вы напишете больше двух почти одинаковых строк, сразу смотрите как это можно преобразовать в цикл, функцию или класс.
- Вы меняете в Label, фактически, только текст, так и меняйте текст а не метку. lbl['text'] = "новый вопрос"
- Все вопросы собирайте в кортежи, так вам легче будет по ним пробегаться, и легче, если что их заменять на другие.
- Используйте .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()