Edit; tkinter weight converter - python

If i input an integer i get invalid. I want it to do invalid if its not a number 0 or greater. Any help greatly appreciated!
from Tkinter import *
import tkMessageBox
from Tkinter import *
import tkMessageBox
class MyApp(object):
def __init__(self):
self.root = Tk()
self.root.wm_title("Question 7")
self.label = Label(self.root, text="Enter weight in pounds",
font=('Calibri', 50))
self.label.pack(padx=20,pady=10)
self.labeltext = StringVar()
self.labeltext.set("")
Label(self.root, textvariable=self.labeltext).pack()
self.entrytext = StringVar()
Entry(self.root, textvariable=self.entrytext).pack()
self.entrytext.trace('w', self.entry_changed)
self.root.mainloop()
def entry_changed(self, a, b, c):
s = self.entrytext.get()
try:
a=int(s)*4.3
self.labeltext.set(a)

The problem is the first boolean condition. The condition is evaluating as true
>>> 'Not A Number' >= 0
True
However, when it then goes to cast it as an integer, it fails:
>>> int('Not A Number')
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
int('Not A Number')
ValueError: invalid literal for int() with base 10: 'Not A Number'
Try this instead so you can properly catch and manage the exception that is being caused:
def entry_changed(self, a, b, c):
s = self.entrytext.get()
try:
a=int(s)*4.3
self.labeltext.set(a)
except:
if s=="":
self.labeltext.set("")
else:
self.labeltext.set("invalid")
Note, that when the user enters a float eg. 4.3 it will also generate an exception so you might want to correct that too.

Related

What causes an exception in Tkinter callback? [duplicate]

This question already has an answer here:
TypeError: 'NoneType' object is not callable with tkinter
(1 answer)
Closed 1 year ago.
I'm trying to make a program that you can add infinite rooms to, so all of my code is built around using one variable to deduce which room is which. However when I run it, it gives me an error that doesn't directly reference any one line in my code, and since I'm a pretty new programmer, I don't know what it means. Also my code is pretty all over the place and incomplete. Thanks for any help!
The error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\SCA0023\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
TypeError: 'NoneType' object is not callable
The Code
from tkinter import *
root = Tk()
class Room:
def __init__(self, items):
self.objects = []
self.objects.append(items)
def list(self):
print(self.objects)
def addkitchenmenu(r): #add a new option menu attributed to a new room
globals()[f'kitchenvar_{r}'] = StringVar(root)
globals()[f'kitchenvar_{r}'].set("Add an appliance")
globals()[f'kitchenvar_{r}'].trace('w', applianceadd(r))
kitchenitems = ['Kettle', 'Toaster']
globals()[f'appliancelist_{r}'] = OptionMenu(root, globals()[f'kitchenvar_{r}'], *kitchenitems).pack()
addkitchen(r)
def applianceadd(r): #add a new room
globals()[f'kobjects_{r}'] = []
globals()[f'kobjects_{r}'].append(globals()[f'kitchenvar_{r}'].get())
items = globals()[f'kobjects_{r}']
globals()[f'kroom_{r}'] = Room(items)
globals()[f'kroom_{r}'].list()
def addkitchen(r): #add an appliance
globals()[f'addappliace{r}'] = Button(root, text='add appliance', command=lambda: applianceadd(r))
def newkitchencheck(): #find the next name for a room that isn't taken
varnotfound = True
a = 0
while varnotfound:
if f'kroom{a}' in globals():
a += 1
else:
r = a
varnotfound = False
addkitchenmenu(r)
addroombutton = Button(root, text="add kitchen", command=newkitchencheck)
addroombutton.pack()
root.mainloop()
You are passing result of applianceadd(r) (which is None) to .trace(). Change to .trace("w", lambda *_: applianceaddr(r)).

Connecting multiple entries with class and function tkinter

I made one program using Python (tkinter). When you click the button "Add Task" new row is created. User needs to enter values in "Size [m2]" and "Total Cost" entries, and when he/she clicks the button "Sum Values", in entry box under cost/m2 should be inserted value "Total Cost"/"Size [m2]" and sum of all values under cost/m2 (sum should be in "answerE")
I made it so that It can sum the values that are entered in entry box under cost/m2, but i cant make it to do the "Total Cost"/"Size [m2]" and to insert that answer under cost/m2 and then sums it. I always get this error:
CostSize=float(CostEntry.get())/float(SizeEntry.get())
NameError: name 'CostEntry' is not defined
And I want this:
What should I do, so that it recognizes the CostEntry?
This is the code:
from tkinter import *
from tkinter import ttk
myApp = Tk()
myApp.title("APP")
myApp.geometry("1000x650")
frame1=LabelFrame(myApp,text=" Activities ")
frame1.grid(row=0,column=0,padx=5)
i=Label(frame1, text=" i ")
i.grid(row=0,column=1)
ProjectName=Label(frame1, text=" Project name ")
ProjectName.grid(row=0,column=2)
SizeLabel=Label(frame1, text="Size [m2]")
SizeLabel.grid(row=0,column=3)
TotalCostLabel=Label(frame1, text="Total Cost")
TotalCostLabel.grid(row=0,column=4)
CostSizeLabel=Label(frame1, text="Cost/m2")
CostSizeLabel.grid(row=0,column=5)
newrow=1
class AddNewTask(object):
rowlist=[]
def update_row_values(self):
for i,entry in enumerate(self.rowlist):
entry.delete(0, 'end')
entry.insert(0,i+1)
def addTask(self):
def delete():
try:
sum = int(answerE.get())
entry_value = int(prodEntry.get())
new_sum = sum - entry_value
answerE.delete(0, 'end')
answerE.insert(0, sum)
except ValueError:
pass
bdelete.destroy()
iEntry.destroy()
ProjectEntry.destroy()
SizeEntry.destroy()
CostEntry.destroy()
CostSizeEntry.destroy()
CostSizeEntry.destroy()
self.rowlist.remove(iEntry)
self.update_row_values()
self.entrylist.remove(CostSizeEntry)
global newrow
newrow=newrow+1
bdelete=Button(frame1,text="-",command=delete)
bdelete.grid(row=newrow,column=0,sticky="E",padx=4)
iEntry=Entry(frame1,width=3)
self.rowlist.append(iEntry)
iEntry.grid(row=newrow,column=1,padx=1)
n = len(self.rowlist)
iEntry.insert(0,n)
ProjectEntry=Entry(frame1,width=75)
ProjectEntry.grid(row=newrow,column=2,padx=1)
SizeEntry=Entry(frame1,width=10)
SizeEntry.grid(row=newrow,column=3,padx=1)
CostEntry=Entry(frame1,width=10)
CostEntry.grid(row=newrow,column=4,padx=1)
CostSizeEntry=Entry(frame1,width=10)
CostSizeEntry.grid(row=newrow,column=5,padx=1)
self.entrylist.append(CostSizeEntry)
def __init__(self):
buttonadd=Button(frame1,text="Add Task",command=self.addTask)
buttonadd.grid(row=0,column=0,padx=3,pady=5)
self.entrylist = []
def sumValues():
try:
CostSize=float(CostEntry.get())/float(SizeEntry.get())
CostSizeEntry.insert(0,CostSize)
except ValueError:
pass
sum = 0
for entry in AddNewTask.entrylist:
try:
sum += float(entry.get())
except ValueError:
pass
answerE.delete(0, 'end')
answerE.insert(0, sum)
sumButton = Button(frame1, text="Sum Values", command=sumValues)
sumButton.grid(row=0, column=7)
AddNewTask=AddNewTask()
frame2=LabelFrame(myApp,text=" Answer")
frame2.grid(row=0,column=1,padx=5,sticky="N")
answerL=Label(frame2, text="Answer: ")
answerL.grid(row=0,column=0)
answerE=Entry(frame2,width=10)
answerE.grid(row=0, column=1)
myApp.mainloop()
The CostEntry variable is created in a class method. However, it is created with local scope. This means that when the method ends, so does the reference to CostEntry. And the next time you call the method (to destroy the object), it doesn't exist.
Solution: Use the self attribute to create an instance of the variable.
self.CostEntry=Entry(frame1,width=10)
self.CostEntry.grid(row=newrow,column=4,padx=1)
and when you go to delete it:
self.CostEntry.destroy()
You should use self attribute with variables that are used out of local scope. Try this:
from tkinter import *
from tkinter import ttk
myApp = Tk()
myApp.title("APP")
myApp.geometry("1000x650")
frame1=LabelFrame(myApp,text=" Activities ")
frame1.grid(row=0,column=0,padx=5)
i=Label(frame1, text=" i ")
i.grid(row=0,column=1)
ProjectName=Label(frame1, text=" Project name ")
ProjectName.grid(row=0,column=2)
SizeLabel=Label(frame1, text="Size [m2]")
SizeLabel.grid(row=0,column=3)
TotalCostLabel=Label(frame1, text="Total Cost")
TotalCostLabel.grid(row=0,column=4)
CostSizeLabel=Label(frame1, text="Cost/m2")
CostSizeLabel.grid(row=0,column=5)
newrow=1
class AddNewTask(object):
rowlist=[]
def update_row_values(self):
for i,entry in enumerate(self.rowlist):
entry.delete(0, 'end')
entry.insert(0,i+1)
def addTask(self):
def delete():
try:
sum = int(answerE.get())
entry_value = int(prodEntry.get())
new_sum = sum - entry_value
answerE.delete(0, 'end')
answerE.insert(0, sum)
except ValueError:
pass
bdelete.destroy()
iEntry.destroy()
ProjectEntry.destroy()
self.SizeEntry.destroy()
self.CostEntry.destroy()
self.CostSizeEntry.destroy()
self.rowlist.remove(iEntry)
self.update_row_values()
self.entrylist.remove(CostSizeEntry)
global newrow
newrow=newrow+1
bdelete=Button(frame1,text="-",command=delete)
bdelete.grid(row=newrow,column=0,sticky="E",padx=4)
iEntry=Entry(frame1,width=3)
self.rowlist.append(iEntry)
iEntry.grid(row=newrow,column=1,padx=1)
n = len(self.rowlist)
iEntry.insert(0,n)
ProjectEntry=Entry(frame1,width=75)
ProjectEntry.grid(row=newrow,column=2,padx=1)
self.SizeEntry=Entry(frame1,width=10)
self.SizeEntry.grid(row=newrow,column=3,padx=1)
self.CostEntry=Entry(frame1,width=10)
self.CostEntry.grid(row=newrow,column=4,padx=1)
self.CostSizeEntry=Entry(frame1,width=10)
self.CostSizeEntry.grid(row=newrow,column=5,padx=1)
self.entrylist.append(self.CostSizeEntry)
def __init__(self):
buttonadd=Button(frame1,text="Add Task",command=self.addTask)
buttonadd.grid(row=0,column=0,padx=3,pady=5)
self.entrylist = []
self.sumButton = Button(frame1, text="Sum Values", command=self.sumValues)
self.sumButton.grid(row=0, column=7)
def sumValues(self):
try:
CostSize=float(self.CostEntry.get())/float(self.SizeEntry.get())
self.CostSizeEntry.insert(0,CostSize)
except ValueError:
pass
sum = 0
for entry in AddNewTask.entrylist:
try:
sum += float(entry.get())
except ValueError:
pass
answerE.delete(0, 'end')
answerE.insert(0, sum)
AddNewTask=AddNewTask()
frame2=LabelFrame(myApp,text=" Answer")
frame2.grid(row=0,column=1,padx=5,sticky="N")
answerL=Label(frame2, text="Answer: ")
answerL.grid(row=0,column=0)
answerE=Entry(frame2,width=10)
answerE.grid(row=0, column=1)
myApp.mainloop()

Function not working as intended, python, TKinter

Im having trouble calling an variable from a function within another function.
I have two functions:
def refineRate(event):
if refineRate(event) == int():
refine = int(refineRate(event))
return refine
else:
refine = float(refineRate(event))
return refine
and:
def veldCalc(event):
minValue = open("mineral_value.csv", "r")
veld = minValue.readlines()[0]
minValue.close()
veld = veld[0:3]
veld = int(veld)
veld = veld / 100 * refineRate(event)
refinedVeld = veld * int(veldCalc)
print (refinedVeld)
I also have two entry where the user of the calculator can enter some figures.
repro = Label(root, text="Reprocessing %")
repro_entry = Entry(root)
repro.grid(row=0, column=0)
repro_entry.grid(row=0, column=1)
veld = Label(root, text="Veldspar: ")
veld_entry = Entry(root)
veld.grid(row=1, column=0)
veld_entry.grid(row=1, column=1)
repro_entry.bind("<KeyPress>", refineRate)
veld_entry.bind("<KeyPress>", veldCalc)
What i need is for the user to input there refineRate and which should then get passed through the function and stored for later use. the when they enter the amount they have, the veldCalc function should then pull the users refine rate from the previous function and do the math but im getting the following errors
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Ganjena\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "C:/Users/Ganjena/Desktop/Course/Projects/helloworld/ORE FUNCTIONS/Ore Calculator.py", line 5, in refineRate
if refineRate(event) == int():
File "C:/Users/Ganjena/Desktop/Course/Projects/helloworld/ORE FUNCTIONS/Ore Calculator.py", line 5, in refineRate
if refineRate(event) == int():
File "C:/Users/Ganjena/Desktop/Course/Projects/helloworld/ORE FUNCTIONS/Ore Calculator.py", line 5, in refineRate
if refineRate(event) == int():
[Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceede
any idea to why this isn't working? Thank you in advance.
You seem to have a misconception of how to get the user-input value inside a tk.Entry widget. The proper way is to use the .get() method on the widget.
Here is a minimal example to get you started:
# (Use Tkinter/tkinter depending on Python version)
import Tkinter as tk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.repro = tk.Label(self, text="Reprocessing %")
self.repro_entry = tk.Entry(self)
self.repro.grid(row=0, column=0)
self.repro_entry.grid(row=0, column=1)
self.repro_entry.bind("<Return>", self.refineRate)
self.mainloop()
def refineRate(self, evt):
# Get the user input and print it in the terminal
userRepro = self.repro_entry.get()
print(userRepro)
# Launch the GUI
app = App()
Then, to check whether the user input is a float or an int, you can use the technique described in this link.

Develop a GUI interface to perform bitwise AND, OR, NOT, XOR operation on two decimal numbers with explanation using python

I want to make a python program to look like this
so I have made a code similar looking this:
from Tkinter import *
import Tkinter
import tkMessageBox
top=Tkinter.Tk()
def and1(a,b):
print int(a and b)
def or1(a,b):
print int(a or b)
def not1(a):
print int(not a)
def xor1(a,b):
print int((a and not b) or (not a and b))
def exit1(top):
top.destroy()
def exit2(top):
top.destroy()
def expl():
top=Tkinter.Tk()
l1=Label(top,text="Number 1").grid(row=0,column=0)
e1=Entry(top,bd=5)
e1.grid(row=0,column=1)
e3=Entry(top,bd=5)
l3=Label(top,text="Binary Number 1").grid(row=0,column=2)
e3.grid(row=0,column=3)
l2=Label(top,text="Number 2").grid(row=1,column=0)
e2=Entry(top,bd=5)
e2.grid(row=1,column=1)
l4=Label(top,text="Binary Number 2").grid(row=1,column=2)
e4=Entry(top,bd=5)
e4.grid(row=1,column=3)
l5=Label(top,text="t.f.p.r.s").grid(row=2,column=2) #says text from previous radiobutton selection
e5=Entry(top,bd=5)
e5.grid(row=2,column=3)
l6=Label(top,text="Decimal Result").grid(row=3,column=1)
e6=Entry(top,bd=5)
e6.grid(row=3,column=2)
b1=Tkinter.Button(top,bd=5,text="Exit",command=lambda top=top:exit2(top)).grid(row=4,column=0)
top.mainloop()
L1=Label(top,text="Number 1").grid(row=0,column=0)
E1=Entry(top,bd=5)
E1.grid(row=0,column=1)
L2=Label(top,text="Number 2").grid(row=0,column=2)
E2=Entry(top,bd=5)
E2.grid(row=0,column=3)
var=IntVar()
R1=Radiobutton(top,text="AND",variable=var,value=1,command="and1")
R1.grid(row=1,column=0)
R2=Radiobutton(top,text="OR",variable=var,value=2,command="or1")
R2.grid(row=1,column=1)
R3=Radiobutton(top,text="NOT",variable=var,value=3,command="not1")
R3.grid(row=2,column=0)
R4=Radiobutton(top,text="XOR",variable=var,value=4,command="xor1")
R4.grid(row=2,column=1)
label=Label(top)
label.grid()
B1=Tkinter.Button(top,text="Result is:",command="result",bd=5)
B1.grid(row=3,column=0)
B2=Tkinter.Button(top,text="Explanation",command=expl,bd=5)
B2.grid(row=3,column=1)
B3=Tkinter.Button(top,bd=5,text="Exit",command=lambda top=top:exit1(top)).grid(row=3,column=2)
L3=Label(top,text="Result is:").grid(row=4,column=0)
E3=Entry(top,bd=5)
E3.grid(row=4,column=1)
top.mainloop()
Now modified. I want that user should input values in first frame and get result accordingly, also on explanation click, other frame opens and explains using that previous values only.
I don't know what to say. I prefer not to completely solve the problem for you, but I wanted to get a better understanding of Python's Tkinker. Read up on classes, it will help in the future.
#!/usr/bin/python
from Tkinter import *
import Tkinter
import tkMessageBox
top=Tkinter.Tk()
res = 0
tfprs = ""
def and1(a,b):
global res
res = int(a and b)
def or1(a,b):
global res
res = int(a | b)
def not1(a):
global res
res = int(not a)
def xor1(a,b):
global res
res = int((a and not b) or (not a and b))
def result(event=None):
global top,res,E3
text = StringVar()
E3=Entry(top,textvariable=text,bd=5)
E3.grid(row=4,column=1)
text.set(str(res))
def exit1(top):
top.destroy()
def exit2(top):
top.destroy()
def selected():
global tfprs
tfprs = var.get()
def expl(a,b):
global top,tfprs,res
binary1 = StringVar()
binary2 = StringVar()
top1=Tkinter.Toplevel(top)
value1 = IntVar()
l1=Label(top1,text="Number 1").grid(row=0,column=0)
e1=Entry(top1,textvariable = value1,bd=5)
value1.set(a)
e1.grid(row=0,column=1)
e3=Entry(top1,textvariable = binary1,bd=5)
l3=Label(top1,text="Binary Number 1").grid(row=0,column=2)
binary1.set(format(a,'b'))
e3.grid(row=0,column=3)
value2 = IntVar()
l2=Label(top1,text="Number 2").grid(row=1,column=0)
e2=Entry(top1,textvariable = value2,bd=5)
value2.set(b)
e2.grid(row=1,column=1)
l4=Label(top1,text="Binary Number 2").grid(row=1,column=2)
e4=Entry(top1,textvariable = binary2,bd=5)
binary2.set(format(b,'b'))
e4.grid(row=1,column=3)
l5=Label(top1,text="t.f.p.r.s").grid(row=2,column=2) #says text from previous radiobutton selection
operator = StringVar()
e5=Entry(top1,textvariable = operator,bd=5)
operator.set(tfprs)
operator.set(tfprs)
e5.grid(row=2,column=3)
dres = IntVar()
l6=Label(top1,text="Decimal Result").grid(row=3,column=1)
e6=Entry(top1,textvariable = dres ,bd=5)
dres.set(res)
e6.grid(row=3,column=2)
b1=Tkinter.Button(top1,bd=5,text="Exit",command=lambda top=top1:exit2(top1)).grid(row=4,column=0)
top.mainloop()
def dotwo(a,b):
selected()
expl(a,b)
num1 = IntVar()
L1=Label(top,text="Number 1").grid(row=0,column=0)
E1=Entry(top,textvariable = num1,bd=5)
num1.set(1)
E1.grid(row=0,column=1)
num2 = IntVar()
L2=Label(top,text="Number 2").grid(row=0,column=2)
E2=Entry(top,textvariable =num2,bd=5)
num2.set(1)
E2.grid(row=0,column=3)
var=StringVar()
R1=Radiobutton(top,text="AND",variable=var,value="AND",command=lambda: and1(int(E1.get()),int(E2.get())))
R1.grid(row=1,column=0)
R2=Radiobutton(top,text="OR",variable=var,value="OR",command=lambda: or1(int(E1.get()),int(E2.get())))
R2.grid(row=1,column=1)
R3=Radiobutton(top,text="NOT",variable=var,value="NOT",command=lambda: not1(int(E1.get())))
R3.grid(row=2,column=0)
R4=Radiobutton(top,text="XOR",variable=var,value="XOR",command=lambda: xor1(int(E1.get()),int(E2.get())))
R4.grid(row=2,column=1)
label=Label(top)
label.grid()
B1=Tkinter.Button(top,text="Result is:",command=result,bd=5)
B1.grid(row=3,column=0)
B2=Tkinter.Button(top,text="Explanation",command=lambda:dotwo(int(E1.get()),int(E2.get())),bd=5)
B2.grid(row=3,column=1)
B3=Tkinter.Button(top,bd=5,text="Exit",command=lambda top=top:exit1(top)).grid(row=3,column=2)
L3=Label(top,text="Result is:").grid(row=4,column=0)
E3=Entry(top,bd=5)
E3.grid(row=4,column=1)
top.mainloop()

Timer App Type Error I Can't See

I'm quite new to python I have run into a type error but I personally can't see it. Help will be appreciated. I am using windows 7.
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:\Users\Kids\Desktop\Python Tests\Clock2.py", line 18, in mclock
mlable = Label(mGui, str(z), "minute(s) has past.").pack()
TypeError: __init__() takes from 1 to 3 positional arguments but 4 were given
Code:
import sys
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
import os
from time import sleep
def mclock():
x = 1
z = 0
while x != -1:
mlable = Label(mGui,text = "str(x) second(s)").pack()
x = x+1
sleep(1)
if x == 60:
x = 1
z = z+1
mlable = Label(mGui, str(z), "minute(s) has past.").pack()
return
mGui = Tk()
mGui.geometry("300x200+100+100")
mGui.title("Jono's Clock")
menubar = Menu(mGui)
filemenu = Menu(menubar, tearoff = 0)
filemenu.add_command(label = "Clock",command = mclock)
menubar.add_cascade(label = "File",menu = filemenu)
mGui.config(menu = menubar)
mGui.mainloop()
Also if any one knows haw to add a clear function to clear the seconds each time it ticks that will be appreciated as well.
The label initializer, like all Python methods, has a self first arguments. It accepts only up to two additional positional arguments (the master and cfg arguments), but you are giving 3:
Label(mGui, str(z), "minute(s) has past.")
You probably wanted to concatenate those two strings; you'll have to pass this in explicitly as the text keyword argument:
Label(mGui, text=str(z) + " minute(s) has past.")

Categories