Tkinter trying simple math using GUI - python

Trying to make a very basic addition calculator with python and tkinter. It gives me an error:
btresult = Button(window, text = "Compute Sum", command = self.result).grid(row = 4, column = 2, sticky = E)
^
SyntaxError: invalid syntax
I am having trouble figuring out how to connect this.
from tkinter import *
class addCalculator:
def __init__(self):
window = Tk()
window.title("Add Calculator")
Label(window, text = "First Number: ").grid(row = 1, column = 1, sticky = W)
Label(window, text = "Second Number: ").grid(row = 2, column = 1, sticky = W)
self.number1Var = StringVar()
Entry(window, textvariable = self.number1Var, justify = RIGHT).grid(row = 1, column = 2)
self.number2Var = StringVar()
Entry(window, textvariable = self.number2Var, justify = RIGHT).grid(row = 2, column = 2)
self.resultVar = StringVar()
lblresult = Label(window, textvariable = self.result.grid(row = 3, column = 2, sticky = E)
btresult = Button(window, text = "Compute Sum", command = self.result).grid(row = 4, column = 2, sticky = E)
def result(self):
resultVar = self.resultVar.set(eval(self.number1Var.get()) + eval(self.number2Var.get()))
return resultVar
window.mainloop()
addCalculator()

On the previous line (lblresult = ...), you forgot to close your opened parentheses. Python interprets this (both that line and the next line, btresult = ...) as one whole line of code, but obviously this can't work with your code, hence the SyntaxError

I solved this problem in my own way. I tried to stay faithful to the original question but the code needed a lot of clean up. There was lots of little odds and ends to fix, but i think the main problem was the method of passing the integers to the function. I also changed the original lblresult from a label to an Entry widget. Im still new at Python but getting better. I found this question while looking for a similar answer and solving this also solved my problem. Thanks! Code below:
from Tkinter import *
class addCalculator:
def __init__(self):
window = Tk()
window.title("Add Calculator")
def result(z1,z2):
biz=z1+z2
lblresult.delete(0,END)
lblresult.insert(0,biz)
return
Label1 = Label(window, text = "First Number: ").grid(row = 1, column = 1, sticky = W)
Label2 = Label(window, text = "Second Number: ").grid(row = 2, column = 1, sticky = W)
self.number1Var = IntVar()
Entry1 = Entry(window, textvariable = self.number1Var, justify = RIGHT).grid(row = 1, column = 2)
self.number2Var = IntVar()
Entry2 = Entry(window, textvariable = self.number2Var, justify = RIGHT).grid(row = 2, column = 2)
Label3 = Label(window, text = "Result: ").grid(row = 3, column = 1, sticky = W)
lblresult = Entry(window, justify = RIGHT)
lblresult.grid(row = 3, column = 2, sticky = E)
btresult = Button(window,text="Compute Sum",command=lambda:result(self.number1Var.get(),self.number2Var.get()))
btresult.grid(row = 4, column = 2, sticky = E)
window.mainloop()
addCalculator()

Related

Can i Make Labels Clickable in tkinter and get the Value of label clicked?

I would like user to click on the number's and then the number should change color and i shall be able to capture on what label user has clicked, this form then shall be saved in Text and PDF format..Thanks a mil in advance for any help
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Proj_pres:
"""Defininf clickable labels in frame"""
#def fr_lb(self):
def __init__(self,master):
master.title(" Feedback Form")
#master.resizable(False,False)
self.frame_header = ttk.Frame(master, borderwidth = 5, relief ='ridge').grid(sticky = NE)
#self.frame_header.pack()
ttk.Label(self.frame_header, text = " For recording feedback on Autumn(inerm) project presentations",
font=('Arial',16,'bold')).grid(row = 0, column = 0,sticky = NW)
"""Defining new frame"""
self.frame_content = ttk.Frame(master,borderwidth = 5)
self.frame_content.grid(row = 2, column = 0,columnspan = 3, sticky = NW)
"""Adding check buttons for Studio 1 and Studio 2"""
self.chkb1 = IntVar()
self.b1 = ttk.Checkbutton(self.frame_content, text = "UC1Studio1", variable = self.chkb1).grid(row =0,column = 0)
self.chkb2 = IntVar()
self.b2 = ttk.Checkbutton(self.frame_content, text = "UC2Studio2", variable = self.chkb2).grid(row = 0, column = 8,columnspan = 2,stick=W)
"""Adding Labels for Team and Reviewer"""
ttk. Label(self.frame_content, text = "Team Name").grid(row =4, column = 0,sticky = W)
ttk.Label(self.frame_content, text = "Reviewer").grid(row = 4,column = 7, sticky = E)
ttk.Label(self.frame_content).grid(row=2, column=0)
"""Adding Entry Boxes for team name and reviewer"""
ttk.Entry(self.frame_content).grid( row = 4, column = 1,columnspan = 4,sticky = W)
ttk.Entry(self.frame_content).grid( row = 4, column = 8,columnspan = 2, sticky = E)
"""Adding Label and frame for grading info"""
self.frame_info = ttk.Frame(master,borderwidth = 5, relief = 'solid')
self.frame_info.grid(row = 3, column = 0,sticky = NW)
ttk.Label(self.frame_info).grid(row =5,column = 0)
ttk.Label(self.frame_info, text ="Please use the feeedback scale for each of the following criterion, "
"where 5 = excellent and 1 = poor").grid(row = 7, column = 0,sticky = W)
ttk.Label(self.frame_info).grid(row = 6, column =0)
ttk.Label(self.frame_info,text = "OVERVIEW OF PROJECT").grid(row = 8, column = 0, sticky = NW)
ttk.Label(self.frame_info, text = " 5: Well Structured,4: Clear aim, 3:Understandable project "
"view").grid(row = 9, column = 0, sticky = NW)
ttk.Label(self.frame_info, text=" 2: Absent,1: Confused "
"view").grid(row=9, column=5, sticky=NW)
#ttk.Label(self.frame_info, text=" should come here").grid(row=9, column=1, sticky=NW)
"""Adding frame in column 2 for clickable Labels"""
self.frame_clk=ttk.Frame(self.frame_info, borderwidth= 5, relief ='solid')
self.frame_clk.grid(row = 9,column = 2,columnspan = 3,sticky = NW)
self.f1_l5 = StringVar()
l5 = ttk.Label(self.frame_clk,text = " 5 " ,
background = 'white',borderwidth=5,relief= 'ridge',font =('Helvetica',12,'bold'))
#,textvariable = self.f1_l5
l5.grid(row=0,column =1,columnspan =2 )
f1_l4= ttk.Label(self.frame_clk, text=" 4 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l4.grid(row =0 , column = 3)
f1_l3 = ttk.Label(self.frame_clk, text=" 3 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l3.grid(row=0, column=4)
f1_l2 = ttk.Label(self.frame_clk, text=" 2 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l2.grid(row=0, column=5)
f1_l1 = ttk.Label(self.frame_clk, text=" 1 ",background = 'white', borderwidth=5,relief= 'ridge',font=('Helvetica', 12, 'bold'))
f1_l1.grid(row=0, column=6)
#elf.frame_content.pack()
def main():
root = Tk()
proj_pres = Proj_pres(root)
root.mainloop()
if __name__ == '__main__':main()
def clickFunction(event): #event is argument with info about event that triggered the function
global selectedNumber #make the number visible throughout the program, don't need this if you'll just pass it as argument to function
event.widget.config(background = "green") #event.widget is reference to widget that was clicked on and triggered the function
selectedNumber = 7 - event.widget.grid_info()["column"] #grid info is dictionary with info about widget's grid relative to widget, more at http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-methods.html
if(selectedNumber > 5): selectedNumber = 5
print(selectedNumber)
''' if someday you won't use grid, but will use list to store Labels, this is a way to get Label's position
selectedNumber = myLabels.index(event.widget)
'''
l5.bind("<Button-1>", clickFunction)
f1_l4.bind("<Button-1>", clickFunction)
f1_l3.bind("<Button-1>", clickFunction)
f1_l2.bind("<Button-1>", clickFunction)
f1_l1.bind("<Button-1>", clickFunction)
''' Alternative way for making lots of similar widgets, not to mention extending Label class
myLabels = [] #create List to make code more compact and to be able to use loops
for i in range(5, 0, -1):
myLabels.append(ttk.Label(self.frame_clk, text=" " + str(i) + " ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
myLabels.bind("<Button-1>", clickFunction)
myLabels[i].grid(row =0 , column = 6 - i)
'''
Here is code you can add below "f1_l1.grid(row=0, column=6)" line (around ln 77). But I think you might need RadioButton for that purpose since it automatically unmarks other options and supports IntVar. More about events: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/events.html This webpage has excellent (but a bit outdated) documentation.
Btw, there is one quick fix you might want to apply when making programs for yourself. In Python you can add fields to classes and their instances outside their definition. E.g. in your code, you cold have written f1_l1.myNumber = 1 after "creating" it and in clickFunction instead of grid_info() use selectedNumber = event.widget.myNumber. It'd do the thing, but don't tell them I taught you that ;) since it isn't considered good practice adding fields that way.
If you have any more questions feel free to ask.

How to store a string in a empty list and display the results in a listbox

Hello Python community,
Im using Python 3.6 and Im stumped on how to display a stored item in an empty list to a list box. Can anyone evaluate my code and tell me what I'm missing? Thanks in advance!
from tkinter import *
root = Tk()
root.title("Name Entry")
root.geometry("240x250")
mylist = []
def get_data(l):
l.append(box1.get())
print(l)
label1 = Label(root,text = "ID:",height = 2)
label1.grid(row = 0, column = 0)
ID=StringVar()
box1 = Entry(root, bd = 4, textvariable = ID)
box1.grid(row = 0, column = 1)
botonA = Button(root, text = "accept",command=lambda: get_data(mylist), width = 5)
botonA.grid(row = 0, column = 2)
list_names = Listbox(root).grid(row = 2, column = 1, rowspan = 7)
for item in mylist:
list_names.insert("end", item)
root.mainloop()
With the help from Matteo, I was able to creat what I wanted. Thanks again for clearing this up for me! :)
{from tkinter import *
root = Tk()
root.title("Name Entry")
root.geometry("240x250")
mylist = []
def get_data(l):
l.append(box1.get())
print(l)
display_data()
def display_data():
list_names.delete(0, "end")
for items in mylist:
list_names.insert(END, items)
label1 = Label(root,text = "ID:",height = 2)
label1.grid(row = 0, column = 0)
ID = StringVar()
box1 = Entry(root, bd = 4, textvariable = ID)
box1.grid(row = 0, column = 1)
botonA = Button(root, text = "accept",command = lambda: get_data(mylist),
width = 5)
botonA.grid(row = 0, column = 2)
list_names = Listbox(root)
list_names.grid(row = 2, column = 1, rowspan = 7)
root.mainloop()}
You have to insert the element when the button is pressed! In your code you are adding it to the listbox when mylist was empty.
Here is the working code:
from tkinter import *
root = Tk()
root.title("Name Entry")
root.geometry("240x250")
mylist = []
def get_data(l):
l.append(box1.get())
list_names.insert(END, l)
print(l)
label1 = Label(root, text="ID:", height=2)
label1.grid(row=0, column=0)
ID = StringVar()
box1 = Entry(root, bd=4, textvariable=ID)
box1.grid(row=0, column=1)
botonA = Button(root, text="accept", command=lambda: get_data(mylist), width=5)
botonA.grid(row=0, column=2)
list_names = Listbox(root)
list_names.grid(row=2, column=1, rowspan=7)
root.mainloop()
I also modified two other things:
I'm not sure if it's what you wanted but l.append(box1.get()) adds to the listbox all the element of the list, and not just the last one as I think you need.
list_names = Listbox(root).grid(row = 2, column = 1, rowspan = 7) means that the list_names variable is the result of the grid function (which is None). You have to first save the ListBox variable, and the grid it.

how to return a value to the main function after clicking a button in tkinter?

In this file, I tried to return the value of employNum and employPass to the main function each time I clicked the display button. How can I do that?
from tkinter import *
def displayButton(root,employNum, employPass):
Label(root,text = employNum.get() ).grid(row = 3, column = 1, sticky = N+S+W+E)
Label(root, text = employPass.get()).grid(row = 4, column = 1, sticky = N+S+W+E)
def main():
root = Tk()
Label(root, text = 'Employee Number: ').grid(row = 0, column = 0, sticky = W)
Label(root, text = 'Login Password: ').grid(row = 1, column = 0, sticky = W)
employeeNum = StringVar()
employeePass = StringVar()
Entry(root, textvariable = employeeNum).grid(row = 0, column = 1, columnspan = 2, sticky = W)
Entry(root, textvariable = employeePass).grid(row = 1, column = 1, columnspan = 2, sticky = W)
checkButton = BooleanVar()
Checkbutton(root, text = 'Remember Me', variable = checkButton).grid(row = 2, column = 1, sticky = W)
Button(root, text = 'Save', relief = RAISED).grid(row = 2, column = 2, sticky = E)
display = Button(root, text = 'Display', relief = RAISED, command = lambda: displayButton(root, employeeNum,employeePass))
display.grid(row = 3, column = 2, sticky = E)
Label(root, text = "Employee's number is ").grid(row = 3, column = 0, sticky = W)
Label(root, text = "Employee's Passowrd is ").grid(row =4 , column = 0, sticky = W)
root.mainloop()
main()
Button can't return value using return. You can only set value in global variable or passed as argument. You can change text in Label assigned to global variable or passed as argument. You can create new Label but root have to be global variable or passed as argument.

TKinter math output to canvas.create_text

I am trying to calculate a formula and display its output as a table in TKinter. Since it is not working, I am just trying to get a simple result and print it to a canvas widget. When this gets working I will do the entire loan formula. As it is I get no output in the GUI or in the console.
Is this even possible to place the result of a calculation as text in canvas.create_text?
from tkinter import * # Import tkinter
width = 500
height = 500
class MainGUI:
def __init__(self):
window = Tk() # Create a window
window.title(" Loan Schedule ") # Set title
frame1 = Frame(window)
frame1.grid(row = 1, column = 1)
Label(frame1, text = " Loan Amount ").grid(row = 1, column = 1, sticky = W)
self.v1 = StringVar()
Entry(frame1, textvariable = self.v1, justify = RIGHT).grid(row = 1, column = 2)
Label(frame1, text = " Years ").grid(row = 1, column = 3, sticky = W)
self.v2 = StringVar()
Entry(frame1, textvariable = self.v2, justify = RIGHT).grid(row = 1, column = 4)
btCalculate = Button(frame1, text = " Calculate ", command = self.calculate()).grid(row = 1, column = 5, sticky = E)
frame2 = Frame(window)
frame2.grid(row = 2, column = 1)
self.canvas = Canvas(frame2, width = width, height = height, bg = "white")
self.canvas.pack()
self.canvas.create_text(25, 25, text = self.calculate(), tags = "text")
window.mainloop() # Create an event loop
def calculate(self):
result = self.v1.get() + self.v2.get()
print(result)
return result
MainGUI()
command require function name without ()
command = self.calculate
so now it works
from tkinter import * # Import tkinter
width = 500
height = 500
class MainGUI:
def __init__(self):
window = Tk() # Create a window
window.title(" Loan Schedule ") # Set title
frame1 = Frame(window)
frame1.grid(row = 1, column = 1)
Label(frame1, text = " Loan Amount ").grid(row = 1, column = 1, sticky = W)
self.v1 = StringVar()
Entry(frame1, textvariable = self.v1, justify = RIGHT).grid(row = 1, column = 2)
Label(frame1, text = " Years ").grid(row = 1, column = 3, sticky = W)
self.v2 = StringVar()
Entry(frame1, textvariable = self.v2, justify = RIGHT).grid(row = 1, column = 4)
btCalculate = Button(frame1, text = " Calculate ", command = self.calculate).grid(row = 1, column = 5, sticky = E)
frame2 = Frame(window)
frame2.grid(row = 2, column = 1)
self.canvas = Canvas(frame2, width = width, height = height, bg = "white")
self.canvas.pack()
self.canvas.create_text(55, 10, text = self.add_text(), tags = "text")
window.mainloop() # Create an event loop
def calculate(self):
result = int(self.v1.get()) + int(self.v2.get())
self.canvas.create_text(25, 25, text = result, tags = "text")
print(result)
return result
def add_text(self):
return "HELLO WORLD"
MainGUI()
by the way: line below means - run self.calculate() and result assign to command
command = self.calculate()

Deleting a Label in Python Tkinter?

I am trying to hide everything in this function:
def addHome(self):
Label(self, text = "Would you like to add to your to-do list, or generate a random item?", bg="#efefef").grid(row = 3, columnspan = 2, sticky="W")
self.txtHome = Entry(self)
self.btnAddToIt = Button(self, text = "Add To It!", bg="#efefef")
self.btnAddToIt.grid(row = 4, columnspan = 2)
self.btnAddToIt["command"] = self.addToIt
self.btnRandom = Button(self, text = "Random!", bg="#efefef")
self.btnRandom.grid(row = 5, columnspan = 2)
self.btnRandom["command"] = self.addRandom
So that I can show the things in these functions:
def addToIt(self):
#self.clearMiddle()
Label(self, text = "Add To List").grid(row = 3, columnspan = 2)
self.addInput()
self.btnProcessAdd = Button(self, text = "Add To It!", bg="#efefef")
self.btnProcessAdd.grid(row = 7, column = 0)
self.btnProcessAdd["command"] = self.processAdd
self.btnCancel = Button(self, text = "Cancel", bg="#efefef")
self.btnCancel.grid(row = 7, column = 1)
self.btnCancel["command"] = self.addHome
def addInput(self):
#adds input for add to item page
Label(self, text = "Name of Item:", bg="#efefef", width=50).grid(row=3, column=0)
self.nameOfItem = Entry(self)
self.nameOfItem.grid(row = 3, column = 1)
self.nameOfItem.insert(0, "Be Awesome")
Label(self, text = "Item Category:", bg="#efefef", width=50).grid(row = 4, column = 0, sticky="E")
self.itemCategory = Listbox(self, height = 5)
self.itemCategory.grid(row = 4, column = 1)
self.itemCategory.insert(END, "Fun", "School", "Work", "Exercise", "Other")
Label(self, text = "Other Item Details:", bg="#efefef", width=50).grid(row = 5, column = 0, sticky="E")
self.otherItemDetails = Text(self, width=22, height=3)
self.otherItemDetails.grid(row = 5, column = 1)
Label(self, text = "Due Date (mm/dd/yy):", bg="#efefef", width=50).grid(row = 6, column = 0, sticky="E")
self.dueDate = Entry(self)
self.dueDate.grid(row = 6, column = 1)
self.dueDate.insert(0, "06/19/2013")
Then vice versa when the Cancel button is hit (clearing the things in addToIt and addInput). Is there any way I can do this?
Yes, there is some way. I see you are using grid. So, to hide an object use Object.grid_forget().
Just in case, if you use pack, you can hide an object by Object.pack_forget(). Same thing works with place.
I have some idea, that might come in handy. I recommend you to have all objects you want to hide simultaneously in a single Frame, so you will just use Frame.grid_forget() instead of
Obj1.grid_forget()
Obj2.grid_forget()
Obj3.grid_forget()
.
.
.
Remember that using this will only make any object invisible, but it still exists "within" memory with all its properties.

Categories

Resources