Проблема с окнами tkinter
Сначала хотелось бы показать непосредственно код:
from tkinter import *
#test1 - приятно ли с вами общаться
#test2 - благоразумие
count=0
#класс для вопроса
class Question(object):
def __init__(self, number, question_text):
"""Constructor"""
self.number = number
self.question_text = question_text
def create_question(self):
global count
question_window = Tk()
question_window.title(f"Вопрос {self.number}")
question_window.geometry('500x500+100+100')
question_number = Label(question_window, text=(f"Вопрос номер {self.number}"), font="Arial 20", background="gray93", justify=CENTER)
question_number.place(relx=0, rely=0.3, relwidth=1, relheight=0.1)
question_number = Label(question_window, text=(f"{self.question_text}"), font="Arial 10", background="gray93", justify=CENTER)
question_number.place(relx=0, rely=0.4, relwidth=1, relheight=0.1)
def answer_yes():
global count
count+=1
question_window.destroy()
def answer_no():
question_window.destroy()
answer_yes = Button(question_window, text="Да", background="gray90", font="Arial 16", command=answer_yes)
answer_no = Button(question_window, text="Нет", background="gray90", font="Arial 16", command=answer_no)
answer_yes.place(relx=0.73, rely=0.7, relwidth=0.15, relheight=0.1)
answer_no.place(relx=0.1, rely=0.7, relwidth=0.15, relheight=0.1)
question_window.mainloop()
#основное окно, должно открываться после каждого прохождения теста, по нажатию кнопки
def main_window():
root = Tk()
root.title("Психологический тест")
root.geometry('700x700+100+100')
choose_lab = Label(root, text="Выберите тест", width=30, height=1, font="Arial 20", background="gray93")
choose_lab.place(x=100, y=1)
test2_but = Button(root, text="Приятно ли с Вами общаться?", width=30, height=2, font="Arial 20", background="gray90", command=test1_fun)
test2_but.place(x=100, y=180)
test3_but = Button(root, text="Благоразумны ли Вы?", width=30, height=2, font="Arial 20", background="gray90", command=test2_fun)
test3_but.place(x=100, y=380)
root.mainloop()
#вопросы
test1_question1 = Question(number=1, question_text="Вы любите больше слушать, чем говорить?")
test1_question2 = Question(number=2, question_text="Вы любите больше слушать, чем говорить?")
test1_question3 = Question(number=3, question_text="Вы любите больше слушать, чем говорить?")
test1_question4 = Question(number=4, question_text="Вы любите больше слушать, чем говорить?")
test1_question5 = Question(number=5, question_text="Вы любите больше слушать, чем говорить?")
test1_question6 = Question(number=6, question_text="Вы любите больше слушать, чем говорить?")
test1_question7 = Question(number=7, question_text="Вы любите больше слушать, чем говорить?")
test1_question8 = Question(number=8, question_text="Вы любите больше слушать, чем говорить?")
test1_question9 = Question(number=9, question_text="Вы любите больше слушать, чем говорить?")
test1_question10 = Question(number=10, question_text="Вы любите больше слушать, чем говорить?")
test1_question11 = Question(number=11, question_text="Вы любите больше слушать, чем говорить?")
test2_question1 = Question(number=1, question_text="Вы любите больше слушать, чем говорить?")
test2_question2 = Question(number=2, question_text="Вы любите больше слушать, чем говорить?")
test2_question3 = Question(number=3, question_text="Вы любите больше слушать, чем говорить?")
test2_question4 = Question(number=4, question_text="Вы любите больше слушать, чем говорить?")
test2_question5 = Question(number=5, question_text="Вы любите больше слушать, чем говорить?")
test2_question6 = Question(number=6, question_text="Вы любите больше слушать, чем говорить?")
test2_question7 = Question(number=7, question_text="Вы любите больше слушать, чем говорить?")
test2_question8 = Question(number=8, question_text="Вы любите больше слушать, чем говорить?")
test2_question9 = Question(number=9, question_text="Вы любите больше слушать, чем говорить?")
test2_question10 = Question(number=10, question_text="Вы любите больше слушать, чем говорить?")
test2_question11 = Question(number=11, question_text="Вы любите больше слушать, чем говорить?")
#функция первого теста, здесь возможные проблемы
def test1_fun():
global count
def test1_shutdown():
test1.destroy()
def test1_start():
def test1_end():
test1_end_window = Tk()
test1_end_window.title("Тест 2. Результат")
test1_end_window.geometry('500x500+100+100')
count_label = Label(test1_end_window, text=(f"Вы набрали {count} баллов"), font="Arial 20",
background="gray93", justify=CENTER)
count_label.place(relx=0, rely=0.3, relwidth=1, relheight=0.1)
test1_result = Label(test1_end_window, text=(f"1"), font="Arial 10", background="gray93", justify=CENTER)
test1_result.place(relx=0, rely=0.4, relwidth=1, relheight=0.1)
test1_exit = Button(test1_end_window, text="Завершить", background="gray90", font="Arial 16",
command=main_window)
test1_exit.place(relx=0.7, rely=0.7, relwidth=0.30, relheight=0.1)
test1_descr.destroy()
test1_ready.destroy()
test1_notready.destroy()
test1.destroy()
root.destroy()
test1_question1.create_question()
test1_question2.create_question()
test1_question3.create_question()
test1_question4.create_question()
test1_question5.create_question()
test1_question6.create_question()
test1_question7.create_question()
test1_question8.create_question()
test1_question9.create_question()
test1_question10.create_question()
test1_question11.create_question()
test1_end()
#print(count)
test1 = Tk()
test1.title("Тест 1. Приятно ли с Вами общаться?")
test1.geometry('500x500+100+100')
test1_descr = Label(test1, text="Вы готовы пройти тест из 11 вопросов?", font="Arial 20", background="gray93", justify=CENTER)
test1_descr.place(relx=0, rely=0.3, relwidth=1, relheight=0.1)
test1_ready = Button(test1, text="Да", background="gray90", font="Arial 16", command=test1_start)
test1_notready = Button(test1, text="Нет", background="gray90", font="Arial 16", command=test1_shutdown)
test1_ready.place(relx=0.73, rely=0.7, relwidth=0.15, relheight=0.1)
test1_notready.place(relx=0.1, rely=0.7, relwidth=0.15, relheight=0.1)
#функция второго теста, здесь возможные проблемы
def test2_fun():
global count
def test2_shutdown():
test2.destroy()
def test2_start():
def test2_end():
test2_end_window = Tk()
test2_end_window.title("Тест 2. Результат")
test2_end_window.geometry('500x500+100+100')
count_label = Label(test2_end_window, text=(f"Вы набрали {count} баллов"), font="Arial 20", background="gray93", justify=CENTER)
count_label.place(relx=0, rely=0.3, relwidth=1, relheight=0.1)
test2_result = Label(test2_end_window, text=(f"1"), font="Arial 10", background="gray93", justify=CENTER)
test2_result.place(relx=0, rely=0.4, relwidth=1, relheight=0.1)
test2_exit = Button(test2_end_window, text="Завершить", background="gray90", font="Arial 16", command=main_window)
test2_exit.place(relx=0.7, rely=0.7, relwidth=0.30, relheight=0.1)
test2_descr.destroy()
test2_ready.destroy()
test2_notready.destroy()
root.destroy()
test2.destroy()
test2_question1.create_question()
test2_question2.create_question()
test2_question3.create_question()
test2_question4.create_question()
test2_question5.create_question()
test2_question6.create_question()
test2_question7.create_question()
test2_question8.create_question()
test2_question9.create_question()
test2_question10.create_question()
test2_question11.create_question()
test2_end()
#print(count)
test2 = Tk()
test2.title("Тест 2. Благоразумны ли вы?")
test2.geometry('500x500+100+100')
test2_descr = Label(test2, text="Вы готовы пройти тест из 11 вопросов?", font="Arial 20", background="gray93", justify=CENTER)
test2_descr.place(relx=0, rely=0.3, relwidth=1, relheight=0.1)
test2_ready = Button(test2, text="Да", background="gray90", font="Arial 16", command=test2_start)
test2_notready = Button(test2, text="Нет", background="gray90", font="Arial 16", command=test2_shutdown)
test2_ready.place(relx=0.73, rely=0.7, relwidth=0.15, relheight=0.1)
test2_notready.place(relx=0.1, rely=0.7, relwidth=0.15, relheight=0.1)
#первое основное окно, используется из-за некоторых багов, функции тестов не воспринимают имя root из функции main_window
root = Tk()
root.title("Психологический тест")
root.geometry('700x700+100+100')
choose_lab = Label(root, text="Выберите тест", width=30, height=1, font="Arial 20", background="gray93")
choose_lab.place(x=100, y=1)
test2_but = Button(root, text="Приятно ли с Вами общаться?", width=30, height=2, font="Arial 20", background="gray90", command=test1_fun)
test2_but.place(x=100, y=180)
test3_but = Button(root, text="Благоразумны ли Вы?", width=30, height=2, font="Arial 20", background="gray90", command=test2_fun)
test3_but.place(x=100, y=380)
root.mainloop()
И текст ошибки:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\clash\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\clash\PycharmProjects\pythonProject\тест.py", line 130, in test2_start
root.destroy()
File "C:\Users\clash\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 2341, in destroy
self.tk.call('destroy', self._w)
_tkinter.TclError: can't invoke "destroy" command: application has been destroyed
Эта ошибка возникает, когда после прохождения одного теста я хочу начать второй, и наоборот, если прошёл второй и хочу пройти первый. Второй не запускается. Как я понял, root.destroy()в функциях test1_start и test2_start не работает, т.к. пытается удалить окно, которого уже нет. Мне нужно, чтобы пользователь мог проходить сколько угодно тестов без перезапуска программы. Также наблюдается проблема в том, что экраны окончания test1_end_window и test2_end_window не закрываются, после нажатия кнопки test1_exit и test2_exit соответственно. Нужно, чтобы эта кнопка закрывала окно завершения и открывала основное окно root с выбором теста. В коде закомментированы некоторые пояснения к нему. Заранее спасибо.
Ответы (2 шт):
Я не разобрался в чем ошибка, как-то все свалено в кучу. Очень много окрывающихся и закрывающихся окон.
- Нужно основное окно(root) для выбора теста.
- Oно открывает окно второго уровня (Toplevel) с 1-м вопросом.
- При ответе на вопрос, текст в метках Label должен меняться на следущий вопрос.
- Когда вопросы закончаться выдается результат. Чтоб легко изменять метки, в будущем вопросы и проверочные ответы надо их собрать в кортежи.Почитайте сайт https://younglinux.info/tkinter/tkinter. Хотел добавить заготовку программы, но редактор пишет, что она не отформатирована и не пропускает.
Вот скинул заготовку программы на gist https://gist.github.com/SergioKoh/4c60eceb197e999ce2ab3f1ca4977497