This is a fairly common class of problems associated with GUI programming. The heart of the problem is the window drawing manager. While your function is running, the drawing manager is frozen; updating the label text will not have a visible effect until your function ends. Therefore, if you have a for loop with the sleep(1) command inside, all it does is freeze everything for five seconds before updating its final value when the function finally finishes.
The solution is to use the after method, which tells Tkinter to call the specified function at some point in the future. Unlike sleep , this gives the room manager a breathing room that requires updating your window.
One possible way to do this is to register six events with after : five for intermediate name label updates and one for the final name and pop change.
def spin(self): def change_name(): index = random.randrange(len(self.name_list)) self.lbl["text"] = self.name_list[index] self.lbl.grid() def finish_spinning(): index = random.randrange(len(self.name_list)) self.lbl["text"] = self.name_list[index] self.lbl.grid() self.name_list.pop(index) if self.name_list: name_changes = 5 for i in range(name_changes): self.after(100*i, change_name) self.after(100*name_changes, finish_spinning) else: self.lbl["text"] = "No more names" self.lbl.grid()
(disclaimer: this is just a simple example of how you can use after , and may not be suitable for actual use. In particular, it can behave badly if you press the spin button several times while the names are already spinning Also, code duplication between change_name and finish_spinning pretty ugly)
Kevin source share