Reputation: 27
I went through the topics here at stack overflow, but could not understand anything. (yes, I've seen that the answer has been answered, but really couldnt understand.)
So, here's the thing. I'm building small application that will pair couples from a group for a tournament we're having. I successfully built the algorithm that pair the players, and I've decided to make this a bit more approachable to everyone and started looking at ktinker.
I've managed to get my application to show something like this:
Title
info
info
info
info
info
Button
The button suppose to re-run the whole thing (next round) and it works. I've managed to get it with the appropriate title, and even added a new button at the end of the screen. the only problem I'm having is that I want to get rid of all the text above. destroy it and just draw on a new page.
Now, the code:
from tkinter import *
root = Tk()
root.title("Tournament")
root.geomerty("50x180")
app = Frame(root)
app.grid()
run_application() # my pairings
#inside the code i'm pairing the players and then:
for players in player_paired:
label=Label(app, text=players[0]+' vs. '+players[1] # its a tuple
label.grid()
button=Button(app,text="Next Round", command=run_application)
button.grid()
#end of run_application
root.mainloop()
So, I've tried adding to the beginning of my "run_application" the next rows:
app.destroy()
app = Frame(root)
app.grid()
and got "UnboundLocalError: local variable 'app' referenced before assignment"
Would anyone help? i can't figure this out. (If able to write example, it would help a lot)
Ofek.
Upvotes: 0
Views: 14293
Reputation: 299
In my experience, I found it easier to delete the elements. Here is something you can do. I don't honestly have much time, so I will use examples from my code, instead of editing your code.
So for your labels you could do this.
labels = []
for players in player_paired:
label=Label(app, text=players[0]+' vs. '+players[1] # its a tuple
label.grid()
labels.append(label)
Then to remove the text have a method that does something like this.
for label in labels:
label.destroy()
And then go back to the start after that.
Upvotes: 0
Reputation: 385970
The simplest solution is to put everything you want to destroy in a frame, and then you can simply destroy and recreate the frame, or destroy all of the children in the frame.
In your specific case, make the parent of button
be root
, and then you can destroy and recreate the contents of app
each time you press the button.
Here is an example. I took the liberty of switching the way you're importing, to be PEP8 compliant:
import tkinter as tk
from random import shuffle
participants = [
"Fred Flintstone", "Barney Rubble", "Wilma Flintstone", "Betty Rubble"
]
def get_pairings():
'''for simulation purposes, this simply randomizes the participants'''
global participants
# see http://stackoverflow.com/a/23286332/7432
shuffle(participants)
return zip(*[iter(participants)]*2)
def reset():
'''Reset the list of participants'''
for child in app.winfo_children():
child.destroy()
for players in get_pairings():
label = tk.Label(app, text="%s vs. %s" % players)
label.grid()
root = tk.Tk()
root.title("Tournament")
app = tk.Frame(root)
app.grid()
button=tk.Button(root,text="Next Round", command=reset)
button.grid()
# this sets up the first round
reset()
root.mainloop()
Upvotes: 1