Я создаю простую программу с графическим интерфейсом, которая использует Python и Tkinter для регистрации времени / даты, когда пользователь нажимает кнопку на интерфейсе (путем добавления информации в файл .txt), а также для отправки электронного письма список адресов, информирующих получателей об обновлении журнала.
Программа имеет три основных кадра / экрана, по которым я бы хотел, чтобы пользователь перемещался. Навигация между экранами должна быть основана на времени. Другими словами, я бы хотел, чтобы пользователь перенаправлялся с основного экрана на дополнительный экран после нажатия кнопки Tkinter (которую я уже установил с помощью аргумента 'command' виджетов Tkinter), а затем автоматически перенаправлял вернуться к главному экрану после 5-секундной задержки.
Я понимаю, что использование time.sleep()
не рекомендуется в программах с графическим интерфейсом. Однако у меня возникли проблемы с реализацией метода Tkinter .after()
, и я не смог достичь желаемого результата.
Я приложил упрощенный пример кода моей программы, который моделирует мою проблему:
import tkinter as tk
class mainApplication(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
for F in (MainScreen, AcknowledgeScreen):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(MainScreen)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class MainScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Press Button to Log Time")
label.pack()
button = tk.Button(self, text="Confirm", command=lambda: controller.show_frame(AcknowledgeScreen))
button.pack()
class AcknowledgeScreen(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Logging Completed. Please Wait.")
label.pack()
# The implementation below is giving me trouble.
self.after(5000, controller.show_frame(MainScreen))
root = mainApplication()
root.mainloop()
Другие решения, которые я попытался (для интересующей линии), включают:
# Attempt 1
self.after(5000, controller.show_frame(MainScreen)) # This code waits 5 seconds before opening the GUI window; does not redirect back to MainScreen from AcknowledgeScreen.
# Attempt 2
root.after(5000, controller.show_frame(MainScreen)) # This code throws an error 'NameError: name 'root' is not defined.
# Attempt 3
label.after(5000, controller.show_frame(MainScreen)) # This code waits 5 seconds before opening the GUI window; does not redirect back to MainScreen from AcknowledgeScreen.
К сожалению, я никогда не сталкивался с объектно-ориентированным программированием до начала работы с Tkinter, поэтому я считаю, что мои ошибки могут быть связаны с фундаментальным неправильным пониманием того, как работает ООП. Тем не менее, я был бы признателен, если бы кто-нибудь мог указать мне правильное направление или уточнить мои ошибки.