appending checkbox interger to list python tkinter - python

I've been coding a program that would let you practice multiplication, on the program, I've made it so the user can select what numbers they want to practice with checkboxes. I've managed to get it working but I was wondering if there is a more iterative way of doing it since i want to go from 1 to 12. I've seen ways of making checkboxes from a list but I haven't been able to get it to work.
from msilib.schema import CheckBox
from tkinter import *
import random
from tkinter import messagebox
class Timestable:
def __init__(self, parent):
self.f1 = Frame(parent)
self.f1.grid()
self.f2 = Frame(parent)
self.f2.grid()
self.f2.grid_forget()
self.f3 = Frame(parent)
self.f3.grid()
self.f3.grid_forget()
#frame 1 ========================================================
Label(self.f1,text="Multiplication Practice").grid()
Label(self.f1,text="Name:").grid()
self.name = Entry (self.f1)
self.name.grid()
Label(self.f1,text="Age").grid()
self.age = Entry (self.f1)
self.age.grid()
self.user = []
self.incorrect=[]
self.checked1 = IntVar()
self.checked2 = IntVar()
self.c1 = Checkbutton(self.f1, text='1',variable=self.checked1,onvalue=1,offvalue=0,command=self.save)
self.c1.grid()
self.c2 = Checkbutton(self.f1, text='2', variable=self.checked2,onvalue=1,offvalue=0,command=self.save)
self.c2.grid()
self.w = Spinbox(self.f1, from_=1, to=5)
self.w.grid()
Button(self.f1,text="Start", command=self.start).grid()
#frame 2 ========================================================
Label(self.f2,text="Frame 2 ").grid()
self.x=0
self.correct=0
sub = lambda: Timestable.Submit(self)
Button(self.f2,text="submit", command=sub).grid()
self.entryWidget = Entry (self.f2)
self.entryWidget.grid()
#frame 3 ========================================================
Label(self.f3,text="Frame 3 ").grid()
# ===============================================================
def save(self):
if self.checked1.get() == 1:
self.user.append(1)
if self.checked2.get() == 1:
self.user.append(2)
#self.user.append(self.checked1.get())
def clear_text(self):
self.entryWidget.delete(0, 'end')
def Questions(self):
number1 = random.choice(self.user)
number2 = random.randrange(1,12)
self.answer = number1 * number2
self.prompt = (str(number1) + " X " + str(number2))
quest = Label(self.f2, text=self.prompt, width=len(self.prompt))
quest.grid()
return self.answer
def start(self):
self.f1.grid_forget()
self.f2.grid()
self.Questions()
def results(self):
self.f2.grid_forget()
self.f3.grid()
def Submit(self):
if self.entryWidget.get() == "":
messagebox.showerror("Error", "Please enter a number.")
elif self.entryWidget.get() == str:
messagebox.showerror("Error", "Please enter a number, not letters.")
else:
if self.answer != int(self.entryWidget.get().strip()):
messagebox.showinfo("Answer", "INCORRECT! Answer: " + str(self.answer))
self.incorrect.append(self.prompt)
else:
messagebox.showinfo("Answer", "CORRECT!")
self.correct = self.correct +1
self.x=self.x+1
if self.x < int(self.w.get()):
self.Questions()
self.clear_text()
else:
self.results()
self.percent = round(self.correct/self.x*100)
Label(self.f3,text="Congrats, you got "+ str(self.percent) +"% of the questions correct" ).grid()
Label(self.f3,text = self.incorrect).grid()
root = Tk()
root.geometry("200x300")
Timestable(root)
root.mainloop()

Instead of creating the checkboxes one by one, you can use a for loop to create them:
class Timestable:
def __init__(self, parent):
...
self.user = []
self.incorrect = []
# -- create those checkboxes
# list to store the tkinter variables for those checkboxes
self.checked = []
# suggest to create those checkboxes inside a frame
# and put 3 checkboxes in a row
frame = Frame(self.f1)
frame.grid()
for i in range(12):
self.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').grid(row=i//3, column=i%3, sticky='ew')
...
Note that I don't require the save(). You can build the self.user inside start():
def start(self):
# get the user selected numbers
self.user = [v.get() for v in self.checked if v.get()]
# you can check the user list
#print(self.user)
if self.user:
# only start the game when there are numbers selected
self.f1.grid_forget()
self.f2.grid()
self.Questions()

Related

I can't change the background of the tkinter canvas in python

Despite using the config() method, my canvas's background color won't change. I've made sure the if statement is correct by using some print statements, I've done some research and this is the only way to change the color of an existing canvas-
google search results for how to change the canvas background color
screenshot of program when executed (the canvas is the white thing with the question text, the score is a label, the check mark and X buttons are buttons, and I've used the grid() methods to make them display)
In addition, after browsing some old questions, one of the potential causes for this was that a new canvas was being created after each iteration, and since I've defined the cavas in the innit() method, this isn't the case.
So what exactly should I do?
QuizBrain Class-
import html
class QuizBrain:
def __init__(self, q_list):
self.question_number = 0
self.score = 0
self.question_list = q_list
self.current_question = None
def still_has_questions(self):
return self.question_number < len(self.question_list)
def next_question(self):
self.current_question = self.question_list[self.question_number]
self.question_number += 1
q_text = html.unescape(self.current_question.text)
return f"Q.{self.question_number}: {q_text}"
def check_answer(self, user_answer):
correct_answer = self.current_question.answer
if user_answer.lower() == correct_answer.lower():
self.score += 1
return True
else:
return False
QuizInterface Class- look at the def give_feedback(self, is_right: bool) method, it's responsible for changing the canvas background which tells the user if they got it right(green) or wrong(red). I've also shared the other classes (above and below) for context and incase the problem is there.
from tkinter import *
from quiz_brain import QuizBrain
THEME_COLOR = "#375362"
class QuizInterface:
def __init__(self, quiz_brain: QuizBrain):
self.quiz = quiz_brain
self.window = Tk()
self.window.config(background=THEME_COLOR, padx=20, pady=20)
self.window.title("Quiz")
self.score_label = Label(text="score: 0", font=("Arial", 20, "italic"), padx=20, pady=20, bg=THEME_COLOR,
fg="white")
self.score_label.grid(row=0, column=1)
self.canvas = Canvas(width=300, height=250, background="white")
self.question_text = self.canvas.create_text(150, 125, text="SAMPLE",
font=("Arial", 20, "italic"), fill="black", width=250)
self.canvas.grid(column=0, row=1, columnspan=2, pady=40)
true_image = PhotoImage(file="images/true.png")
false_image = PhotoImage(file="images/false.png")
self.true_button = Button(image=true_image, command=self.true_pressed)
self.true_button.grid(row=2, column=0)
self.false_button = Button(image=false_image, command=self.false_pressed)
self.false_button.grid(row=2, column=1)
self.get_next_question()
self.window.mainloop()
def get_next_question(self):
question_text = self.quiz.next_question()
self.canvas.itemconfig(self.question_text, text=question_text)
def true_pressed(self):
is_right = self.quiz.check_answer("True")
self.give_feedback(is_right)
def false_pressed(self):
is_right = self.quiz.check_answer("False")
self.give_feedback(is_right)
def give_feedback(self, is_right: bool):
print("Called")
if is_right:
print("Called-2")
self.canvas.configure(bg="green")
print("Executed")
elif not is_right:
print("called-3")
self.canvas.configure(bg="red")
print("Executed")
self.window.after(3000, self.get_next_question)
self.canvas.config(background="white")
Question Class-
class Question:
def __init__(self, q_text, q_answer):
self.text = q_text
self.answer = q_answer
How I get my questions-
import requests
parameters = {
"amount": 10,
"type": "boolean"
}
quiz_data = requests.get(url="https://opentdb.com/api.php", params=parameters)
quiz_data.raise_for_status()
quiz_questions = quiz_data.json()
question_data = quiz_questions["results"]
Main.py-
from question_model import Question
from data import question_data
from quiz_brain import QuizBrain
from ui import QuizInterface
question_bank = []
for question in question_data:
question_text = question["question"]
question_answer = question["correct_answer"]
new_question = Question(question_text, question_answer)
question_bank.append(new_question)
quiz = QuizBrain(question_bank)
quiz_interface = QuizInterface(quiz)
#
# while quiz.still_has_questions():
# quiz.next_question()
#
# print("You've completed the quiz")
# print(f"Your final score was: {quiz.score}/{quiz.question_number}")
Move the line
self.canvas.config(background="white")
from give_feedback function to get_next_question function.

how to create a scoring system

I'm trying to make my scoring system work. it keeps forgetting after I have changed the score once I go back into the class as it is set as 0. How would I change this so the score changes as appropriate?
code:
import random
from tkinter import *
class TimesTableGUI:
def __init__(self, parent, score = 0):
self.score = score
#chooses a random number
num1 = random.randint(1,10)
num2 = random.randint(1,10)
self.answer = num1 * num2
#making labels
entry_label = Label(parent, text = str(num1) + " * " + str(num2))
entry_label.grid(row = 0, column = 0)
self.e1 = Entry(parent, width = 5)
self.e1.grid(row = 0, column = 1)
b1 = Button(parent, text = "Check Answer", command = self.check_answer)
b1.grid(row = 1, column = 0)
b2 = Button(parent, text = "Next", command = self.new_question)
b2.grid(row = 1, column = 1)
self.b1_output = Label(parent, text = self.score)
self.b1_output.grid(row = 2, column = 0)
def check_answer(self): #callback for Check Answer button
#check if users gets correct answer
f = int(self.e1.get())
if f == self.answer:
self.score +=1
self.b1_output.configure(text = self.score)
else:
self.b1_output.configure(text = self.score)
def new_question(self): #callback for Next button to next question
self.b1_output.configure(text = " ")
radiobuttons = TimesTableGUI(root) #restarts the class for new question
if __name__ == "__main__":
root = Tk()
root.title("Task 3")
radiobuttons = TimesTableGUI(root)
root.mainloop()
Try this:
import random
from tkinter import *
class TimesTableGUI:
def __init__(self, parent, score=0):
self.score = score
self.master = parent
self.ask_new_question()
self.b1_output = Label(parent, text="Score = %i" % self.score)
self.b1_output.grid(row=2, column=1)
def ask_new_question(self):
self.question_frame = Frame(self.master)
self.question_frame.grid(row=1, column=1)
#chooses a random number
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
self.answer = num1 * num2
#making labels
entry_label = Label(self.question_frame, text="%i*%i" % (num1, num2))
entry_label.grid(row=0, column=0)
self.e1 = Entry(self.question_frame, width=5)
self.e1.grid(row=0, column=1)
self.check_answer_btn = Button(self.question_frame, text="Check Answer",
command=self.check_answer)
self.check_answer_btn.grid(row=1, column=0)
b2 = Button(self.question_frame, text="Next",
command=self.new_question)
b2.grid(row=1, column=1)
def check_answer(self):
user_answer = int(self.e1.get())
if user_answer == self.answer:
self.score += 1
self.b1_output.configure(text="Score = %i" % self.score)
# So the user can't submit more than 1 correct answer
self.check_answer_btn.config(state="disabled")
def new_question(self):
# Remove the frame (and all of its children)
self.question_frame.destroy()
# Display the new question
self.ask_new_question()
if __name__ == "__main__":
root = Tk()
root.title("Task 3")
radiobuttons = TimesTableGUI(root)
root.mainloop()
I moved all of the widgets that are for the question inside a frame. The frame gets destroyed and recreated each time a new question needs to be displayed. I also made sure the user can't just keep clicking on Check Answer after they got the correct answer already (for that question).
The problem is that when you you call radiobuttons = TimesTableGUI(root) score is getting reset too.
Quick solution: pass score when you call radiobuttons = TimesTableGUI(root, score=self.score) in new_question
Better solution: create a method that reset GUI without reinitialize the entire class.

How can i 'get' the number i have entered into the label widget into a variable?

I I have 2 functions and the second function should run after the button in the first one has been clicked. This works fine, however I need the number that has been entered to go into a variable and so far the .get() function is not working and im not sure what to do.
I have looked at a lot of different examples, including login and sign up gui's however none of them have been able to help.
from tkinter import *
import tkinter.messagebox as box
def enter_rle_1():
enter_rle = Tk() #do not remove
enter_rle.title('Enter RLE') #do not remove
frame = Frame(enter_rle) #do not remove
label_linecount = Label(enter_rle,text = 'Linecount:')
label_linecount.pack(padx=15,pady= 5)
linecount = Entry(enter_rle,bd =5)
linecount.pack(padx=15, pady=5)
ok_button = Button(enter_rle, text="Next", command = linecount_button_clicked)
ok_button.pack(side = RIGHT , padx =5)
frame.pack(padx=100,pady = 19)
enter_rle.mainloop()
def linecount_button_clicked():
Linecount = linecount.get()
if int(Linecount) < 3:
tm.showinfo("Error", "Enter a number over 3")
elif int(Linecount) > 1000000000:
tm.showinfo("Error", "Enter a number under 1,000,000,000")
else:
print("fdsfd")
enter_rle_1()
I expect there to be a popup telling me the number is too big or too small, depending on wether the number is or not, and if it is a good number, i just have it set as a print as some code to test to see if it works before i move on.
Define a String variable for the Entry widget (Make sure it is global defined):
global linecount_STR
linecount_STR = StringVar()
linecount_STR.set('Enter value here')
linecount = Entry(enter_rle,bd =5,textvariable=linecount_STR)
linecount.pack(padx=15, pady=5)
The number entered there can then be read with int(linecount_STR.get()).
i suggest an OO approach, look this code
#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class Main(ttk.Frame):
def __init__(self, parent):
super().__init__()
self.parent = parent
self.vcmd = (self.register(self.validate), '%d', '%P', '%S')
self.linecount = tk.IntVar()
self.init_ui()
def init_ui(self):
self.pack(fill=tk.BOTH, expand=1)
f = ttk.Frame()
ttk.Label(f, text = "Linecount").pack()
self.txTest = ttk.Entry(f,
validate='key',
validatecommand=self.vcmd,
textvariable=self.linecount).pack()
w = ttk.Frame()
ttk.Button(w, text="Next", command=self.on_callback).pack()
ttk.Button(w, text="Close", command=self.on_close).pack()
f.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
def on_callback(self,):
#print ("self.text = {}".format(self.linecount.get()))
x = self.linecount.get()
if x < 3:
msg = "Enter a number over 3"
elif x > 1000000000:
msg = "Enter a number under 1,000,000,000"
else:
msg = "You ahve enter {0}".format(x)
messagebox.showinfo(self.parent.title(), msg, parent=self)
def on_close(self):
self.parent.on_exit()
def validate(self, action, value, text,):
# action=1 -> insert
if action == '1':
if text in '0123456789':
try:
int(value)
return True
except ValueError:
return False
else:
return False
else:
return True
class App(tk.Tk):
"""Start here"""
def __init__(self):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_title()
self.set_style()
frame = Main(self,)
frame.pack(fill=tk.BOTH, expand=1)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("clam")
def set_title(self):
s = "{0}".format('Enter RLE')
self.title(s)
def on_exit(self):
"""Close all"""
if messagebox.askokcancel(self.title(), "Do you want to quit?", parent=self):
self.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
notice this line at the begin....
self.linecount = tk.IntVar()# declare an integer variable
self.vcmd = (self.register(self.validate), '%d', '%P', '%S')#register a function to allow only integer in your text widget.

how to put default text on tkinter's entry widget

so, i opened a question about it yesterday but it got closed saying its a dupe, let me explain my question more specificly then, hoping im not passinng any law here..
im trying to set a default message that will be set as gray and low opacity in the entry widget on tkinter, that after being focused in will dispear.
i managed to do that, but i got into a problem.
the default text is "enter username" for example, but if someone tries to do this user name it says that the username entry is empty which isnt what i wanna do..
i hope you understood my question.
edit: my question is how to do a placeholder text, while allowing the user to input the same text as the placeholder.
thanks in advance, this is my code:
from tkinter import *
from tkinter import messagebox
main = Tk()
main.title("ani gever")
checkbox_var = IntVar()
def delete_user_default(event):
if User_entry.get()!="enter username":
pass
else:
User_entry.delete(0, END)
def delete_password_default(event):
if password_entry.get() !="insert password":
pass
else:
password_entry.delete(0, END)
password_entry.config(show="*")
def return_user_default(event):
if User_entry.get()=="":
User_entry.insert(0, "enter username")
emptyuser=1
else:
pass
def return_password_default(event):
if password_entry.get()=="":
password_entry.insert(0,"insert password")
password_entry.config(show="")
else:
pass
def details(event):
if ((User_entry.get() == "enter username") or (password_entry.get() == "insert password")):
errorLabel.config(text="Username or password is empty!",fg="red")
elif ((" " in User_entry.get()) or " " in password_entry.get()):
errorLabel.config(text="dont use spaces in your password or username!", fg="red")
else:
print ("username:" + User_entry.get() + "\npassword:" + password_entry.get())
errorLabel.config(text="")
#============== define texts=======================
User_label= Label(main,text="Username:")
password_label= Label(main,text="Password:")
User_entry = Entry(main)
password_entry= Entry(main,show="*")
enterButton= Button(main,text="Log in")
errorLabel= Label(main,text="")
#=============default text on entry's=============
password_entry.config(show="")
User_entry.insert(0,"enter username")
password_entry.insert(0,"insert password")
User_entry.bind("<FocusIn>",delete_user_default)
password_entry.bind("<FocusIn>",delete_password_default)
User_entry.bind("<FocusOut>",return_user_default)
password_entry.bind("<FocusOut>",return_password_default)
#=============return user details ===========
User_entry.bind("<Return>",details)
password_entry.bind("<Return>",details)
enterButton.bind("<Button-1>",details)
#=============place everything on screen===========
User_label.grid(row=0,sticky= W)
User_entry.grid(row=0,column=1,sticky= W)
password_label.grid(row=1,sticky= W)
password_entry.grid(row=1,column=1,sticky= W)
enterButton.grid(row=2,sticky=W)
errorLabel.grid(row=3,columnspan=10,sticky= W)
main.mainloop()
Using this answer an is_empty function can be created. It prints True if validated entry is 'empty' and False if not.
import tkinter as tk
class EntryWithPlaceholder(tk.Entry):
def __init__(self, master=None, placeholder="PLACEHOLDER", color='grey'):
super().__init__(master)
self.placeholder = placeholder
self.placeholder_color = color
self.default_fg_color = self['fg']
self.bind("<FocusIn>", self.foc_in)
self.bind("<FocusOut>", self.foc_out)
self.put_placeholder()
def put_placeholder(self):
self.insert(0, self.placeholder)
self['fg'] = self.placeholder_color
def foc_in(self, *args):
if self['fg'] == self.placeholder_color:
self.delete('0', 'end')
self['fg'] = self.default_fg_color
def foc_out(self, *args):
if not self.get():
self.put_placeholder()
def is_empty(widget, empty_color):
if widget.get():
if widget['fg'] == empty_color:
print (True)
else:
print (False)
else:
print (True)
if __name__ == "__main__":
root = tk.Tk()
username = EntryWithPlaceholder(root, "username")
password = EntryWithPlaceholder(root, "password", 'blue')
username.pack()
password.pack()
tk.Button(root, text="Validate",
command=lambda wid=username, clr=username.placeholder_color:
is_empty(wid, clr)).pack()
root.mainloop()

Tkinter Label Updating Issue

[Python 2.7] Hello. I'm working on a simple Tkinter calculator program, but can't seem to get the label to display any text after I push one of the buttons. Here is the code I'm using, some of the button functions are unfinished until I can get the label itself working:
from Tkinter import *
import ttk
"""Calculator"""
#Variables
Entered = ""
#Button Functions
def Natural_Log():
pass
def Exp():
Entered = "^"
def Sin():
pass
def Cos():
pass
def Tan():
pass
def LeftParentheses():
Entered = Entered + "("
def RightParentheses():
Entered = Entered + ")"
def Log():
pass
def XSquared():
Entered = Entered + "**2"
def InvX():
Entered = Entered + "**-1"
def Seven():
Entered = Entered + "7"
def Eight():
Entered = Entered + "8"
def Nine():
Entered = Entered + "9"
def DEL():
Entered = Entered[:1]
def AC():
Entered = ""
def Four():
Entered = Entered + "4"
def Five():
Entered = Entered + "5"
def Six():
Entered = Entered + "6"
def Mult():
Entered = Entered + "*"
def Div():
Entered = Entered + "/"
def One():
Entered = Entered + "1"
def Two():
Entered = Entered + "2"
def Three():
Entered = Entered + "3"
def Plus():
Entered = Entered + "+"
def Minus():
Entered = Entered + "-"
def Zero():
Entered = Entered + "0"
def Decimal():
Entered = Entered + "."
def Ex():
pass
def neg():
pass
def EXE():
pass
#Main Window Setup:
#Root setup
root = Tk()
root.title("Generic Calculator")
#Parent frame setup
mainframe = ttk.Frame(root,padding="8")
mainframe.grid(column=0,row=0,sticky=(N,S,E,W))
mainframe.columnconfigure(0,weight=1)
mainframe.rowconfigure(0,weight=1)
#Button setup
ttk.Button(mainframe,text="ln",command=Natural_Log).grid(column=1,row=2,sticky=W)
ttk.Button(mainframe,text="^",command=Exp).grid(column=2,row=2,sticky=W)
ttk.Button(mainframe,text="sin",command=Sin).grid(column=3,row=2,sticky=W)
ttk.Button(mainframe,text="cos",command=Cos).grid(column=4,row=2,sticky=W)
ttk.Button(mainframe,text="tan",command=Tan).grid(column=5,row=2,sticky=W)
ttk.Button(mainframe,text="(",command=LeftParentheses).grid(column=1,row=3,sticky=W)
ttk.Button(mainframe,text=")",command=RightParentheses).grid(column=2,row=3,sticky=W)
ttk.Button(mainframe,text="log",command=Log).grid(column=3,row=3,sticky=W)
ttk.Button(mainframe,text="x^2",command=XSquared).grid(column=4,row=3,sticky=W)
ttk.Button(mainframe,text="x^-1",command=InvX).grid(column=5,row=3,sticky=W)
ttk.Button(mainframe,text="7",command=Seven).grid(column=1,row=4,sticky=W)
ttk.Button(mainframe,text="8",command=Eight).grid(column=2,row=4,sticky=W)
ttk.Button(mainframe,text="9",command=Nine).grid(column=3,row=4,sticky=W)
ttk.Button(mainframe,text="DEL",command=DEL).grid(column=4,row=4,sticky=W)
ttk.Button(mainframe,text="AC",command=AC).grid(column=5,row=4,sticky=W)
ttk.Button(mainframe,text="4",command=Four).grid(column=1,row=5,sticky=W)
ttk.Button(mainframe,text="5",command=Five).grid(column=2,row=5,sticky=W)
ttk.Button(mainframe,text="6",command=Six).grid(column=3,row=5,sticky=W)
ttk.Button(mainframe,text="*",command=Mult).grid(column=4,row=5,sticky=W)
ttk.Button(mainframe,text="/",command=Div).grid(column=5,row=5,sticky=W)
ttk.Button(mainframe,text="1",command=One).grid(column=1,row=6,sticky=W)
ttk.Button(mainframe,text="2",command=Two).grid(column=2,row=6,sticky=W)
ttk.Button(mainframe,text="3",command=Three).grid(column=3,row=6,sticky=W)
ttk.Button(mainframe,text="+",command=Plus).grid(column=4,row=6,sticky=W)
ttk.Button(mainframe,text="-",command=Minus).grid(column=5,row=6,sticky=W)
ttk.Button(mainframe,text="0",command=Zero).grid(column=1,row=7,sticky=W)
ttk.Button(mainframe,text=".",command=Decimal).grid(column=2,row=7,sticky=W)
ttk.Button(mainframe,text="EXP",command=Ex).grid(column=3,row=7,sticky=W)
ttk.Button(mainframe,text="(-)",command=neg).grid(column=4,row=7,sticky=W)
ttk.Button(mainframe,text="EXE",command=EXE).grid(column=5,row=7,sticky=W)
#Label Setup:
EnteredSetup = StringVar()
ttk.Label(mainframe,textvariable=EnteredSetup).grid(column=1,row=1,columnspan=5)
EnteredSetup.set(Entered)
root.mainloop()
I believe there is a misunderstanding on how StringVar works. The line
EnteredSetup.set(Entered)
does not create some form of link between EnteredSetup and Entered, modifying Entered does not issue updates in EnteredSetup. Your code can be improved a lot too, and you should post something that is only long enough to describe the problem. Said that, consider this reduced version already fixed (note that it could be much smaller):
from Tkinter import Tk, StringVar
import ttk
class Calculator:
def __init__(self, state):
self.state = state
def ac(self):
self.state.set('')
def state_num(self, num):
self.state.set('%s%d' % (self.state.get(), num))
#Main Window Setup:
#Root setup
root = Tk()
root.title("Generic Calculator")
EnteredSetup = StringVar('')
calc = Calculator(EnteredSetup)
#Parent frame setup
mainframe = ttk.Frame(root, padding="8")
mainframe.grid(column=0, row=0)
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
#Button setup
ttk.Button(mainframe, text="AC", command=calc.ac).grid(
column=5, row=4)
ttk.Button(mainframe, text="1", command=lambda: calc.state_num(1)).grid(
column=1, row=6)
ttk.Button(mainframe, text="0", command=lambda: calc.state_num(0)).grid(
column=1, row=7)
#Label Setup:
ttk.Label(mainframe, textvariable=EnteredSetup).grid(
column=1,row=1,columnspan=5)
root.mainloop()
I hope this guides you in the right direction for further adjusting your calculator.

Categories