0

A Python program loop calls on a tkinter function to create a GUI window. Ideally, each window would be destroyed before control passes out of the tkinter function back to the main Python sequence so that a new window can be created on a clear screen on the next pass of the loop. Instead, what happens is all of the windows that have been created remain onscreen until the Python loop finishes, at which time all of the windows are destroyed. Is there a way to manage the event loop to force each window to be destroyed prior to the return from the tkinter function? (I know that one way to hide the problem would be to define the precise x,y location of the windows, so that each subsequent window covers its predecessor/s, but this would just be a cosmetic fix. I want to know how to correct the underlying problem.) Python 3.5, macOS

import os
from tkinter import *
from tkinter.ttk import *

def display(text):
    alert = Tk()
    alert.geometry('370x200')
    var = StringVar()
    var.set(text)
    message = Label(alert, textvariable = var, font=('arial',20)).pack(pady=20)
    okButton = Button(alert, text = 'OK', command = alert.destroy).place(x=225,y=100)

    alert.mainloop()

days = [ 'Mon', 'Tue', 'Wed' ]

for day in days:
    message = "Today is " + day
    display(message)
Cam U
  • 340
  • 3
  • 10

1 Answers1

1

Under normal circumstances you should only have 1 instance of Tk. See Why are multiple instances of Tk discouraged?

Therefore I suggest to use Toplevel instead of multiple instances of Tk so you can only call the relevant one when needed, and have one root window up (which you can hide if needed):

from tkinter import *
from tkinter.ttk import *

root = Tk()
root.withdraw()


def display(text):
    alert = Toplevel()
    alert.geometry('370x200')
    text_var = StringVar()
    text_var.set(text)
    root.v = text_var
    Label(alert, textvariable=text_var, font=('arial', 20)).pack(pady=20)
    Button(alert, text='OK', command=lambda: next_day(alert)).place(x=225, y=100)


def next_day(top):
    top.destroy()
    try:
        display("Today is {}".format(next(days)))
    except StopIteration:
        root.destroy()


days = iter(['Mon', 'Tue', 'Wed'])

display("Today is {}".format(next(days)))

root.mainloop()
Henry Yik
  • 22,275
  • 4
  • 18
  • 40
  • thanks for taking the time to offer that recommendation. It turns out that this seems to be some quirk of older versions of python causing the problem. I couldn't get your version w/ the f-string formatting to work in 3.5, so I tried 3.7.2 & 3.8.1. I discovered that my original version works just fine, with no windows persistence, in both of the more recent versions. – Cam U Jan 09 '20 at 04:15
  • f-string is not the core of the problem - you can use `"{}".format()` if you need to stick with older versions of Python. – Henry Yik Jan 09 '20 at 04:17
  • 1
    Absolutely. Just mentioned the f-string only to note that that was what led me to try upgrading. – Cam U Jan 09 '20 at 04:18