Ive been coding a maths game but stumbled across a problem where I cant clear a text widget. SO after the users get shown a list of incorrect questions and to play the game again, but after playing the game a second time the list doesn't reset. I've added a comment above the text widget I want to clear if that helps.
from tkinter import *
import random
from tkinter import messagebox
class Timestable:
def __init__(self, parent):
Timestable.f1 = Frame(parent,bg='#66bcb9')
Timestable.f1.grid()
Timestable.f2 = Frame(parent,bg='#66bcb9')
Timestable.f2.grid()
Timestable.f2.grid_forget()
Timestable.f3 = Frame(parent,bg='#66bcb9')
Timestable.f3.grid()
Timestable.f3.grid_forget()
Timestable.f4 = Frame(parent,bg='#66bcb9')
Timestable.f4.grid()
Timestable.f4.grid_forget()
#frame 1 ========================================================
Label(self.f1,text="Multiplication Practice",bg='#508484',fg='white').grid(columnspan=2,column=0,row=0)
Label(self.f1,text="Name:",bg='#508484',fg='white').grid(row=1,column=0)
Timestable.name = Entry (self.f1)
Timestable.name.grid(row=1,column=1)
Label(self.f1,text="Age",bg='#508484',fg='white').grid(row=2,column=0)
Timestable.age = Entry (self.f1)
Timestable.age.grid(row=2,column=1)
Timestable.incorrect=[]
Timestable.user = []
Timestable.checked = []
Label(self.f1,text="Select Timestable",bg='#508484',fg='white').grid(columnspan=2,row=3,column=0)
frame = Frame(self.f1)
frame.grid(row=5,column=0, columnspan=2)
for i in range(12):
Timestable.checked.append(IntVar()) # store the tkinter variable for the checkbox
Checkbutton(frame, text=i+1, variable=self.checked[-1], onvalue=i+1, offvalue=0, anchor='w',bg='#66bcb9').grid(row=i//3, column=i%3, sticky='ew')
Label(self.f1,text="Total Questions",bg='#508484',fg='white').grid(row=4,column=0)
Timestable.w = Spinbox(self.f1, from_=1, to=5)
Timestable.w.grid(row=4,column=1)
Button(self.f1,text="Start", command=lambda: data.start(self),bg='#88c43c').grid(columnspan=2, column=0,row=6)
#frame 2 ========================================================
Label(self.f2,text="Multiplication Practice",bg='#508484',fg='white').grid(columnspan=2,column=0,row=0)
self.x=0
self.correct=0
Timestable.questions=Label(Timestable.f2,text="")
Timestable.questions.grid(row=1,column=0)
Timestable.entryWidget = Entry (self.f2)
Timestable.entryWidget.grid(row=1,column=1)
Button(self.f2,text="submit", command=lambda: data.Submit(self),bg='#88c43c').grid(columnspan=2,column=0,row=3)
#frame 3 ========================================================
Label(self.f3,text="Multiplication Practice",bg='#508484',fg='white').grid(columnspan=2,column=0,row=0)
Timestable.congrats=Label(Timestable.f3,text="")
Timestable.congrats.grid(columnspan=2,column=0,row=1)
#this is the widget I want to clear
Timestable.incdisplay = Text(Timestable.f3, width=15,height=10,bg='#d0e4f4')
Timestable.incdisplay.grid(columnspan=2,column=0,row=2)
Button(self.f3,text="next", command=lambda:data.next(self),bg='#88c43c').grid(columnspan=2,column=0,row=3)
#fram 4 ========================================================
Label(self.f4,text="Multiplication Practice",bg='#508484',fg='white').grid(columnspan=2,column=0,row=0)
Label(self.f4,text="Results",bg='#508484',fg='white').grid(columnspan=2,column=0,row=1)
Timestable.my_text=Text(self.f4,width=20,height=10,bg='#d0e4f4')
Timestable.my_text.grid(columnspan=2,column=1,row=2)
Button(self.f4,text="again", command=lambda:data.again(self),bg='#88c43c').grid(columnspan=2,column=0,row=3)
class data:
def saveleader(self):
file=open('Leaderboard.txt',"a")
file.write(Timestable.name.get()+","+Timestable.age.get()+","+str(data.percent)+"%""\n")
file.close
file=open("Leaderboard.txt","r").read()
headers = " ".join(["Name", "Age", "Score"])
output = [i.split(",") for i in file.split("\n") if i]
out_sort = sorted(output, key=lambda x: int(x[2][:-1]), reverse=True)
final = "\n".join([headers, "-"*len(headers),*(" ".join(i) for i in out_sort)])
Timestable.my_text.insert(END, final)
def clear_text(self):
Timestable.entryWidget.delete(0, 'end')
def Questions(self):
number1 = random.choice(Timestable.user)
number2 = random.randrange(1,12)
self.answer = number1 * number2
self.prompt = (str(number1) + " X " + str(number2))
Timestable.questions.configure(text=self.prompt, width=len(self.prompt),bg='#66bcb9')
return self.answer
def start(self):
Timestable.user = [v.get() for v in Timestable.checked if v.get()]
if Timestable.user:
Timestable.f1.grid_forget()
Timestable.f2.grid()
data.Questions(self)
def results(self):
Timestable.f2.grid_forget()
Timestable.f3.grid()
def next(self):
Timestable.f3.grid_forget()
Timestable.f4.grid()
data.saveleader(self)
self.correct=0
data.deletold(self)
def again(self):
Timestable.f4.grid_forget()
Timestable.f1.grid()
def deletold(self):
Timestable.incdisplay.configure(state=NORMAL)
Timestable.incdisplay.delete("1.0",END)
Timestable.incdisplay.configure(state=DISABLED)
def Submit(self):
if Timestable.entryWidget.get() == "":
messagebox.showerror("Error", "Please enter a number.")
else:
if self.answer != int(Timestable.entryWidget.get().strip()):
messagebox.showinfo("Answer", "INCORRECT! Answer: " + str(self.answer))
Timestable.incorrect.append(self.prompt+"\n")
else:
messagebox.showinfo("Answer", "CORRECT!")
self.correct = self.correct +1
self.x=self.x+1
if self.x < int(Timestable.w.get()):
data.Questions(self)
data.clear_text(self)
else:
data.clear_text(self)
data.results(self)
data.percent = round(self.correct/self.x*100)
Timestable.congrats.configure(text="Congrats, you got "+ str(data.percent) +"% of the questions correct",bg='#66bcb9')
self.x=0
for i in Timestable.incorrect:
Timestable.incdisplay.configure(state=NORMAL)
Timestable.incdisplay.insert(END,i)
Timestable.incdisplay.configure(state=DISABLED)
root = Tk()
root.geometry("300x300")
root.configure(bg='#66bcb9')
Timestable(root)
root.mainloop()
Related
I can't seem to update my money counter(var money) when its labeled, I have a button that's supposed to add 0.1 to moneyNum but the money counter doesn't change. I'm new to stack overflow and would appreciate any help.(btw sry if its REALLY messy)
from tkinter import *
import random
from time import sleep
root = Tk()
root.geometry('320x320')
#spacing
spacingTitle = Label(root, text=" \n\n\n\n\n\n\n\n\n")
#title
title = Label(root, text=" \bGamblers Dream\b", font="Helvetica", fg="red")
titleWelcom = Label(root, text=" Welcom to...")
titleWelcom.grid()
title.grid()
#money counter
moneyNum = float(10.0)
money = Label(root, text="money:" + str(moneyNum), font="Helvetica")
money.grid(row=3, column=0)
#moneyClicker
def moneyButtonAdder():
global moneyNum
moneyNum = moneyNum + 0.1
moneyClicker = Button(root, text="click", fg="green", command=moneyButtonAdder)
moneyClicker.grid(row=14)
root.mainloop()
The problem is that once you create a label, you pass the string to it. Label displays the string, and:
changing a string object does not change the label text
changing the integer does not change the string - it lost the whole connection when the new string object was created
So everything is not as procedural as you would have hoped it is.
The solution - use StringVar objects and detect value changes - see this.
So, the solution is:
from tkinter import *
class Observed(object):
"""adapted copy from https://stackoverflow.com/a/6192298/10713244"""
def __init__(self):
self._observed = 10.0
self._observers = []
#property
def observed(self):
return self._observed
#observed.setter
def observed(self, value):
self._observed = value
for callback in self._observers:
print('announcing change')
callback(self._observed)
def bind_to(self, callback):
print('bound')
self._observers.append(callback)
class Observer(object):
def __init__(self, data):
self.text = ''
self.data = data
self.data.bind_to(self.update)
self.tkinter_init()
def update(self, observed):
self.text = 'float: '+str(data._observed)
self.tkinter_update()
def tkinter_init(self):
self.tk = Tk()
self.tvar = StringVar()
self.label = Label(textvariable=self.tvar)
self.label.pack()
def tkinter_update(self):
self.tvar.set(self.text)
if __name__ == '__main__':
data = Observed()
label = Observer(data)
print(label.text)
data.observed = 10.0
print(label.text)
def dec(): data.observed -= 0.1
Button(label.tk, text='decrease', command=dec).pack()
label.tk.mainloop()
Hope that's helpful!
This is a simple math game which is currently in progress. The loop starts off in mainGame() which then proceeds to mainMenu(). I am trying to create 2 frames; mframe and gframe in order to .destroy() the frames later on, essentially clearing the previous interface for the next one (similar to changing pages).
error:
Label(gframe, textvariable=self.question_var).pack() #gframe stands
for game frame NameError: name 'gframe' is not defined
from tkinter import *
from random import randint
root = Tk()
mframe = Frame(root).pack()
gframe = Frame(root).pack()
frame.pack()
start = True
class mainMenu:
def __init__(self):
gframe.destroy() #gets rid of previous interface
title = Label(mframe, text = "main menu").pack() #mfame stands for menu frame
class mainGame:
def __init__(self):
if start == False:
mframe.destroy() #gets rid of previous interface
#question
self.question_var = StringVar()
Label(gframe, textvariable=self.question_var).pack() #gframe stands for game frame
#answer
self.user_answer_var = StringVar()
entry = Entry(gframe, textvariable=self.user_answer_var)
entry.pack()
submit = Button(gframe, text = "submit", command = self.check_answer).pack()
#response output
self.response_var = StringVar()
self.count = 0
self.score = 0
Label(gframe, textvariable=self.response_var).pack()
#starts loop
self.ask_question()
root.mainloop()
def ask_question(self):
if self.count == 1:
self.endGame()
num1 = randint(1, 10)
num2 = randint(1, 10)
self.question_var.set("What is "+str(num1)+" + " +str(num2)+"?")
self.true_answer = num1 + num2
#print(self.true_answer) #testing purposes
def check_answer(self):
self.count += 1
user_answer = self.user_answer_var.get()
#print(user_answer) #testing purposes
if int(user_answer) == self.true_answer:
text = "Good job"
self.score += 1
else:
text = "Oh no"
self.response_var.set(text)
#clear answer for next loop
self.user_answer_var.set("")
self.ask_question()
def endGame(self):
print("endGame")
mainMenu()
mainGame()
As said in the comments above, the pack() method returns None. What you need to do is first create the two frames and assign them to variables, then pack them later. This way, the variables still point to the frame instances and not None.
You should change;
root = Tk()
mframe = Frame(root).pack()
gframe = Frame(root).pack()
frame.pack()
start = True
to;
root = Tk()
mframe = Frame(root)
gframe = Frame(root)
mframe.pack()
gframe.pack()
start = True
The problem I am having is that the function below works fine on the first pass with regards to displaying the chosen value at the top of the OptionMenu before the 'Enter' button is clicked:
First pass
However on a second pass and any future passes to the function the chosen value is not displayed at the top of the OptionMenu (although if selected it will be used) before the 'Enter' Button is pressed:
Second etc. passes
The code is:
def load_create_list(self):
self.app = Toplevel(self.parent)
self.parent.withdraw()
self.app.title("Rgs2")
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
options = ["2", "3", "4", "5", "6", "7"]
self.results=[]
self.ngg=StringVar() #for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(self.app, text="Number of groups")
self.ng.grid(row=2, column=0)
self.ngg.set("3")
self.ng1 = OptionMenu(self.app, self.ngg, *options)
self.ng1.grid(row=2, column=1, ipadx=10)
for i in range(0,len(self.x3)):
self.L1 = Label(self.app,text="Student")
self.L1.grid(row=i+4, column=0)
self.en = Entry(self.app)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+4, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(self.app,text="Student")
self.L2.grid(row=h+4, column=0)
self.em = Entry(self.app)
self.em.grid(row=h+4, column=1)
self.student.append(self.em)
button=Button(self.app,text="enter",command=lambda : self.hallo2()).grid(row=h+7,column=0)
button=Button(self.app,text="Save List",command=lambda : self.save_list2()).grid(row=h+7,column=1)
I have tried everything but can't understand what might be causing this issues. Any help would be gladly appreciated. Seems like very odd behaviour could it be something outside of the function that is causing the issue?
Full code is:
from Tkinter import *
from tkFileDialog import askopenfile
class main_menu:
def __init__(self, parent):
self.myParent = parent
self.myContainer1 = Frame(parent)
parent.title("Random Group Sorter")
self.myContainer1.pack()
self.button1 = Button(self.myContainer1, command = lambda : self.hope())
self.button1.configure(text="Create List", height = 1, width = 20, font=("Arial", 16))
self.button1.pack(side=TOP)
self.button1.focus_force()
self.button3 = Button(self.myContainer1, command = lambda : self.hope1())
self.button3.configure(text="Load List", height = 1, width = 20, font=("Arial", 16))
self.button3.pack(side=TOP)
self.button2 = Button(self.myContainer1, command = lambda : exit(), )
self.button2.configure(text="Exit",height = 1, width = 20, font=("Arial", 16))
self.button2.pack(side=TOP)
def hope(self):
self.myParent.destroy()
create_list()
def hope1(self):
self.myParent.destroy()
load_list()
class create_list():
def __init__(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1 =[]
self.student2 =[]
self.fake_student = []
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5","6")
self.ng.grid(row=2, column=1)
for i in range(3,21):
self.L1 = Label(text="Student")
self.L1.grid(sticky=E)
self.en = Entry(parent)
self.en.grid(row=i, column=1)
self.student.append(self.en)
button=Button(parent,text="Enter",command=lambda : self.hallo()).grid(row=23,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list()).grid(row=23,column=1)
parent.mainloop()
def hallo(self):
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class load_list:
def __init__(self):
self.x = []
self.x3 = []
self.load_clean()
self.root = Tk()
def load_clean(self):#option to load an already created file, cleans unwanted info from the list
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.askopenfile(parent=root)
root.destroy()
self.x = file_name.readlines()
file_name.close()
x2 =self.x[:]
for z in self.x:
if z [0:6]== "Random" or z == '\n' or z[0:5] == "Group":
x2.remove(z)
for c in range (0,len(x2)):
v = x2[c].rstrip()# this strip spaces and \n from each list item and returns the cleaned up string
self.x3.append(v)
self.load_create_list()
def load_create_list(self):
parent = Tk()
self.parent=parent
self.student = []
self.student1=[]
self.gs1=0
self.ng1=0
self.results=[]
self.ngg = StringVar()# for the option menu widget the variable must be a stringVar not a normal string, int etc.
self.ng = Label(text="Number of groups")
self.ng.grid(row=2, column=0)
self.ng = OptionMenu(parent, self.ngg, "2", "3", "4", "5", "6")
self.ng.grid(row=2, column=1)
for i in range(0,len(self.x3)):
self.L1 = Label(text="Student")
self.L1.grid(row=i+3, column=0)
self.en = Entry(parent)
self.en.insert(END, self.x3[i])
self.en.grid(row=i+3, column=1)
self.student.append(self.en)
self.el = int(len(self.student)+1)
for h in range(self.el,self.el+5):
self.L2 = Label(text="Student")
self.L2.grid(row=h+3, column=0)
self.em = Entry(parent)
self.em.grid(row=h+3, column=1)
self.student.append(self.em)
button=Button(parent,text="enter",command=lambda : self.hallo2()).grid(row=h+6,column=0)
button=Button(parent,text="Save List",command=lambda : self.save_list2()).grid(row=h+6,column=1)
parent.mainloop()
def hallo2(self):
self.student2= []
self.gs1 = int(len(self.student))
self.ng1 = int(self.ngg.get())# still need to use .get even though a stringvar
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
for i in self.student1:# this is added as there are duplicate entries in the student list if saved
if i not in self.student2:
self.student2.append(i)
self.parent.destroy()
lis_an(self.student2,self.ng1)
def save_list2(self):
for entry in self.student:
self.student1.append(entry.get())
self.student1 = filter(None, self.student1)
import tkFileDialog
root = Tk()
root.withdraw()
file_name = tkFileDialog.asksaveasfile(parent=root)
root.destroy()
print >>file_name, "\n"
print >>file_name, "\n".join(self.student1)
file_name.close()
class lis_an:
def __init__(self,student1,ng1):
self.student1 = student1
self.ng1=ng1
self.results = []
self.randomList()
def randomList(self): # this creates a random list of students on the course
import random
studentb = self.student1[:]# this is added as otherwise the student list is overwritten
studentc = []
for i in range(len(studentb)):
element = random.choice(studentb)
studentb.remove(element)
studentc.append(element)
self.student1 = studentc
self.partition()
def partition(self): # this creates sub list of the student list containing the groups of students
increment = len(self.student1) / float(self.ng1)
last = 0
i = 1
while last < len(self.student1):
idx = int(round(increment * i))
self.results.append(self.student1[last:idx])
last = idx
i += 1
output(self.results, self.ng1)
class output:
def __init__(self, student, ng1):
self.ng1 = ng1
self.student = student
self.parent = Tk()
for item1 in range (0,len(self.student)):
test1 = "Group " + str(item1+1)+ ":"
v = Label(self.parent, text=test1, font=("Arial", 13))
test = "\n".join(self.student[item1])
w = Label(self.parent, text=test, justify = LEFT, font=("Arial", 12))
v.pack(side="top", anchor="w")
w.pack(side="top", anchor="w")
button=Button(self.parent,text="Repeat",command=lambda : self.join_list()).pack(side="top", anchor="w")
button=Button(self.parent,text="Main Menu",command=lambda : self.menu_link()).pack(side="top", anchor="w")
mainloop()
def join_list(self):#this function creates a new undivided version of student to feed back to lis_an
self.parent.destroy()
self.student = [j for i in self.student for j in i]
lis_an(self.student,self.ng1)
def menu_link(self):#destroys the parent frame and returns back to main menu
self.parent.destroy()
main()
def main():
parent = Tk()
myapp = main_menu(parent)
parent.mainloop()
main()
Very Simple solution to this problem. I was not defining self.ngg as a StringVar in the parent widget so:
self.ngg = StringVar()
Would cause the error, and
self.ngg = StringVar(self.app)
Solves the problem. Not quite sure why this would occur on the second and subsequent uses of the function but not the first.
I need help with a program which uses tkinter. So I try to use a button to cycle trough some pictures, but there are two cycles and when i press one button either disappears or goes back to the first one (it's kinda hard to explain). I was asking myself if I could use some threading here and I need help since I've never used it before.
This is the part of the code:
square1 = Image.open("Square1.jpg")
square1r = ImageTk.PhotoImage(square1)
self.square1img = Label(self.windowSq, image=square1r)
self.square1img.image = square1r
self.square1img.place(x=30, y=100)
square1 = Image.open("Square1a.jpg")
square1r = ImageTk.PhotoImage(square1)
self.square1img = Label(self.windowSq, image=square1r)
self.square1img.image = square1r
self.square1img.place(x=435, y=100)
next = Button(self.windowSq, text="Next", font=self.customFont, relief=GROOVE, command=self.next, cursor='hand2')
next.place(x=185, y=380)
self.num = 0
next1 = Button(self.windowSq, text="Next", font=self.customFont, relief=GROOVE, command=self.next1, cursor='hand2')
next1.place(x=600, y=380)
self.num1 = 0
def next(self):
self.num = self.num + 1
if self.num == 1:
self.square1img.destroy()
square2 = Image.open("Square2.jpg")
square2r = ImageTk.PhotoImage(square2)
self.square2img = Label(self.windowSq, image=square2r)
self.square2img.image = square2r
self.square2img.place(x=30, y=100)
elif self.num == 2:
self.square2img.destroy()
square3 = Image.open("Square3.jpg")
square3r = ImageTk.PhotoImage(square3)
self.square3img = Label(self.windowSq, image=square3r)
self.square3img.image = square3r
self.square3img.place(x=30, y=100)
elif self.num == 3:
self.square3img.destroy()
square4 = Image.open("Square4.jpg")
square4r = ImageTk.PhotoImage(square4)
self.square4img = Label(self.windowSq, image=square4r)
self.square4img.image = square4r
self.square4img.place(x=30, y=100)
elif self.num == 4:
self.square4img.destroy()
square5 = Image.open("Square5.jpg")
square5r = ImageTk.PhotoImage(square5)
self.square5img = Label(self.windowSq, image=square5r)
self.square5img.image = square5r
self.square5img.place(x=30, y=100)
elif self.num == 5:
self.square5img.destroy()
square1 = Image.open("Square1.jpg")
square1r = ImageTk.PhotoImage(square1)
self.square1img = Label(self.windowSq, image=square1r)
self.square1img.image = square1r
self.square1img.place(x=30, y=100)
self.num = 0
self.windowSq.after(50000, self.next)
def next1(self):
self.num1 = self.num1 + 1
if self.num1 == 1:
self.square1img.destroy()
square2 = Image.open("Square2a.jpg")
square2r = ImageTk.PhotoImage(square2)
self.square2img = Label(self.windowSq, image=square2r)
self.square2img.image = square2r
self.square2img.place(x=435, y=100)
elif self.num1 == 2:
self.square2img.destroy()
square3 = Image.open("Square3a.jpg")
square3r = ImageTk.PhotoImage(square3)
self.square3img = Label(self.windowSq, image=square3r)
self.square3img.image = square3r
self.square3img.place(x=435, y=100)
elif self.num1 == 3:
self.square3img.destroy()
square4 = Image.open("Square4a.jpg")
square4r = ImageTk.PhotoImage(square4)
self.square4img = Label(self.windowSq, image=square4r)
self.square4img.image = square4r
self.square4img.place(x=435, y=100)
elif self.num1 == 4:
self.square4img.destroy()
square5 = Image.open("Square5a.jpg")
square5r = ImageTk.PhotoImage(square5)
self.square5img = Label(self.windowSq, image=square5r)
self.square5img.image = square5r
self.square5img.place(x=435, y=100)
elif self.num1 == 5:
self.square5img.destroy()
square1 = Image.open("Square1a.jpg")
square1r = ImageTk.PhotoImage(square1)
self.square1img = Label(self.windowSq, image=square1r)
self.square1img.image = square1r
self.square1img.place(x=435, y=100)
self.num1 = 0
self.windowSq.after(50000, self.next1)
The whole program is in a class (if you are wondering...)
class Window(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(0, 0)
master.title("Arcade Games")
master.geometry("800x600+560+240")
You have a lot of redundant code above. The idea is to first store the images in a list and then cycle through the list. You can have 2 buttons that call 2 different functions (one for each list), 2 lists of images, and 2 counters to keep your place in each list, and then change the image on a Label from whichever list you want (I use a button as below, and note that only one button is created-never destroyed, and just the image is changed each time). Or you can use one class, and 2 instances of the class, passing a different list of images to be loaded to each instance. This is just a simple proof of concept program. Click on the button/image to change it.
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
class ChangeImage():
def __init__(self, root):
self.photos=[]
self.load_images()
self.image_num=0
self.btn = tk.Button(root, image=self.photos[self.image_num], command=self.next_image)
self.btn.grid(row=0)
tk.Button(root, text="Exit", bg="orange", command=root.quit).grid(row=1)
def next_image(self):
self.image_num += 1
if self.image_num >= len(self.photos):
self.image_num=0
## pipe the next image to be displayed to the button
self.btn["image"]=self.photos[self.image_num]
def load_images(self):
""" copy data images to a list that is an instance variable
"""
ladybug_gif_b64='''\
R0lGODlhIAAgALMAAP///wAAADAwMP99Hf8AAP+lAP//AMopUwAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAACH5BAAAAAAALAAAAAAgACAAAwTHEMhJq714hp3lDh0GiqH2UWOVAt96pUIsBLKglWg87Dwv
4xMBj0Asxgg+XKxwLBJrxUGsI5TKnARoVHoLDp5XbNP5cwmNAqwa/aOc13ByrfKOw2UGw1SSxrb+
AWIxeXsAaX92UDQ1Nh6BdneMhQIHkHGSjYaVlmt4epmacp19YAKEoJRspKWrjBapWWGqcm1uB5tj
ok4HZa+3m5wEt5kuhpTAcb+FVL/NzspAfDHPysslMJjEIS0oLygnOMVd0SwcHeDk6errEQA7
'''
grape_gif='''\
R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9PT6Ai8P8A////
/////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYYfh8GIEvpoUZcmtOKAO5rLMva
0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYwYtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eT
YhJDQ3woDGl7foNiKBV7aYeEkHEignKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOs
NYa2q7mcirC5I5FofsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
'''
house='''R0lGODdhFQAVAPMAAAQ2PESapISCBASCBMTCxPxmNCQiJJya/ISChGRmzPz+/PxmzDQyZDQyZDQy
ZDQyZCwAAAAAFQAVAAAElJDISau9Vh2WMD0gqHHelJwnsXVloqDd2hrMm8pYYiSHYfMMRm53ULlQ
HGFFx1MZCciUiVOsPmEkKNVp3UBhJ4Ohy1UxerSgJGZMMBbcBACQlVhRiHvaUsXHgywTdycLdxyB
gm1vcTyIZW4MeU6NgQEBXEGRcQcIlwQIAwEHoioCAgWmCZ0Iq5+hA6wIpqislgGhthEAOw==
'''
## could also be a list of files passed to the class
for photo in (ladybug_gif_b64, grape_gif, house):
self.photos.append(tk.PhotoImage(data=photo))
root=tk.Tk()
CI=ChangeImage(root)
root.mainloop()
I made this simple program that translates from English to a completely different one (randomized English), when it displays the translation it shows spaces as { }. Any suggestions?
from tkinter import *
english = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t',
'u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','!',
'\"','#','$','%','&','\'','\'','(',')','*','+',',','-','.','/',':',';','?','#','[','\\',']','^','_','`','{','|','}','~',' ', ',','\t','\n','\r','\x0b','\x0c']
potatish =['0','1','2','3','4','5','6','7','8','9','a','v','l','d','e','z','j','s','i','x','q','u','f','b','o','y','c','m','t',
'k','p','g','h','n','r','w','A','V','L','D','E','Z','J','S','I','X','Q','U','F','B','O','Y','C','M','T','K','P','G','H','N','R','W','!',
'\"','#','$','%','&','\'','\'','(',')','*','+',',','-','.','/',':',';','?','#','[','\\',']','^','_','`','{','|','}','~',' ', ',','\t','\n','\r','\x0b','\x0c']
class Program(Frame):
""" A Program to translate """
def __init__ (self, master):
"""Initialise the frame"""
Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""Buttons!!!"""
#Text
self.text = Label(self, text = "Please enter some text:")
self.text.grid()
#Field
self.user = Entry(self)
self.user.grid()
#Button
self.translate = Button(self, text = "Translate")
self.translate.grid()
self.translate["command"] = self.update_console
#Output
self.output = Label(self, text = "Output:\n")
self.output.grid()
#finished
self.finished = Label(self, text = "")
self.finished.grid()
def update_console(self):
"""Updates output"""
self.trans = self.translatedef()
self.finished["text"] = self.trans
def translatedef(self):
f = []
i = -1
j = -1
text = self.user.get()
while i != -2:
i+=1
try:
l = english.index(text[i])
f.append(potatish[l])
except:
while j != -2:
j+=1
try:
return f
except:
break
break
root = Tk()
root.title("Potatish")
root.geometry("500x300")
app = Program(root)
root.mainloop()
You are setting the text of the Label to a list, not a string. The empty element of that list is being displayed as {} by Tkinter.
To correct it, form a string from your list before you send it to the Label:
def update_console(self):
"""Updates output"""
self.trans = ''.join(self.translatedef())
self.finished["text"] = self.trans