taking an integer value from an entry widget in tkinter - python

I wrote some simple code to describe my problem: I want to take an integer value from an entry to use it later.I tried also to use a spin box. here is my code:
from tkinter import*
win=Tk()
win.geometry('300x200')
e=Entry(width=10)
e.pack()
y=int(e.get())
print(y*2)
I always get the same error:
y = int(e.get())
ValueError: invalid literal for int() with base 10 ' '
I don't know why this is happening!

ValueError: invalid literal for int() with base 10 ' '
means that you are trying to convert the string "" to an integer. This, of course, is invalid. The reason you are trying to convert an empty string to an integer is that you are not allowing any value to be placed into the entry.
A good way to allow this to happen would be using a button, which calls a function to get the value within the entry and print it. Also, you are missing the line win.mainloop() which you would need at the end of your code.
Here is the example code you are probably asking for:
from tkinter import *
win = Tk()
win.geometry('300x200')
def printVal():
y = int(e.get())
print(y*2)
e = Entry(width=10)
e.pack()
b = Button(text="push me to print the value in e")
b.pack()
win.mainloop()
This code will still return errors if the value in the entry is not a valid integer, so if you want it to be robust, you'll have to play around with it.

there is several problems in your example, for example. in which moment you are trying to get value from Entry?
your code should looks something like:
from tkinter import *
def validate(value):
print (value)
try:
if value:
return int(value)
except:
return None
def calculate():
x = e1.get()
x_validate = validate(x)
if x_validate == None:
e1.delete(0, END)
e1.insert(0, 'you need to enter integer')
Label1.config(text='')
else:
result = x_validate*2
Label1.config(text=result)
win = Tk()
e1 = Entry(win)
e1.grid(row=0, column=0)
Button(win,text='Calculate', command = calculate).grid(row=0, column=1)
Label(win,text='Result').grid(row=1, column=0)
Label1 = Label(win)
Label1.grid(row=1, column=1)
win.mainloop()
Example if you enter integer and press calculate
Example if you enter string and press calculate

Related

Using > operators in Tkinter

So basically, I am trying to create a python program to detect whether the 3 digit number entered by the user is an Armstrong number or not. It's working fine in python, except it's printing the answer 3 times in terminal. But when I use tkinter, I get some problems since I basically just got to know by it just a few hours ago and don't really know how to use it. The problem I get is in > operator, I'm receiving data in Entry() but > operator is for integers so it is giving me type errors.
Here's the error
TypeError: '>' not supported between instances of 'int' and 'Entry'
Here is my code
import re
from tkinter import *
root = Tk()
label = Label(root, text="Enter a 3 digit Number")
label.pack()
num = Entry(root, width=50, bg="orangered")
num.pack()
def myclick():
Sum = 0
temp = num
if 1000 > num > 99:
while temp > 0:
digit = temp % 10
Sum += digit ** 3
temp //= 10
if num == Sum:
label2 = Label(root, num, "is an Armstrong number")
label2.pack()
else:
label3 = Label(root, num, "is not an Armstrong number")
label3.pack()
else:
label4 = Label(root,
"The number you entered is not a 3 digit number, Please Enter a number between 100 and 999")
label4.pack()
MyButton = Button(root, text="Click", command=myclick)
MyButton.pack()
root.mainloop()
All I want is to make this program work in a gui, and stop printing the result thrice. Can anyone help me?
As num is an Entry widget, you cannot use it directly in value comparison. Use int(num.get()) to convert the content to an integer number. You also need to cater invalid input, for example something like "abc", using try / except.
Also you create new label (for showing the result) in each iteration of the while loop, that is why you get 3 labels for each checking. It is better to create the result label once outside myclick() and update it inside the function instead.
Below is the modified myclick():
def myclick():
try:
number = num.get()
value = int(number)
if 999 >= value >= 100:
total = sum(int(digit)**3 for digit in number)
message = f"{value} {'is' if value == total else 'is not'} an Armstrong number"
else:
message = "Enter a number between 100 and 999"
except ValueError:
message = f"'{number}' is not a valid number"
result.config(text=message) # show the result
And create result label outside the function:
result = Label(root)
result.pack()

I am working on my first tkinter project and i need some guidance

Here I've uploaded the entire code. The problem is on entering a non integer in the field, the program halts and it force quits. I tried solving it by using the part of code I've commented out. My solution doesn't work, so any guidance would be helpful.
from tkinter import *
root = Tk()
def sarteg():
**#while True:
# try:
# a= int(e.get())
# except ValueError:
# eror= Label(root,text="Please enter an integer").pack()
# continue
# else:
# break**
a= int(e.get())
if a%2==0:
even=Label(root,text="number is even").pack()
else:
odd=Label(root,text="number is odd").pack()
label1= Label(root, text="Enter an Integer then click on \"FIND OUT\"").pack()
e = Entry(root, width=20)
e.pack()
mybutt= Button(root, text="find out", command=sarteg)
mybutt.pack()
root.mainloop()
I tried the code, it seems to working fine.
You had error on line 5.
You added 2 asterisks.
**#while True:
If you remove the asterisks, it's working fine. Comments can be added by just adding # before the line.
One more thing I'd recommend it to create a common label to show the results. Because every time you check the number a new label appears creating a list of results.
I believe all you really have to do is remove the while True statement. Try this:
def sarteg():
try:
a = int(e.get())
except ValueError:
eror = Label(root, text="Please enter an integer").pack()
return None
if a % 2 == 0:
even = Label(root, text="number is even").pack()
else:
odd = Label(root, text="number is odd").pack()

When I highlight my entry(tkinter) and press backspace, nothing happens?

I'm working on a program regarding math equations, so in my program there are tons of entries but I'm having difficulties clearing them.
For the entries I'm restricting both a character limit and I only allow number and (",") or ("."). If I type for example ' 1000 ' in my entry, then highlight it and press backspace everything works out. But as soon as I type ' 100,25 ' and add a comma into the mix. It wont delete after pressing backspace.
from tkinter import *
root = Tk()
def validatecontent(var):
return (var.isdigit() == bool(var)) or var == (",") or var == (".")
vcmd = (root.register(validatecontent), '%S')
def character_limit6(var):
if len(var.get()) > 0:
var.set(var.get()[:6])
var = StringVar()
entry = Entry(root, textvariable=var, validate='all',
validatecommand=vcmd)
entry.pack()
var.trace("w", lambda *args: character_limit6(var))
root.mainloop()
Edit: It seems that the problem is that it refuses to recognize a string of "," or ".", alternatively a string of numbers and "," / "." as legitimate. The following seems to work:
from tkinter import *
root = Tk()
var = StringVar()
var.trace("w", lambda *args: character_limit6(var))
def validatecontent(var):
return var.isdigit() == bool(var) or "," in var or "." in var
def character_limit6(var):
if len(var.get()) > 0:
var.set(var.get()[:6])
vcmd = (root.register(validatecontent), '%S')
entry = Entry(root, textvariable=var, validate='all',
validatecommand=vcmd)
entry.pack()
root.mainloop()
In the question when you delete a selection the var parameter in validatecontent is a string eg. '0,0' which fails your validation routine.
Do you want to accept only valid float strings?
Are you expecting strings like '1,234.45' or '123,45'?
Below I've assumed '123,45'
Validatecontent tries to convert the string to a float after replacing any ',' with '.'.
If it can it returns true otherwise it returns True only if the string is empty.
from tkinter import *
root = Tk()
def validatecontent(var): # Amended var is now the complete string.
try:
temp = var.replace(',', '.') # Replace ','' with '.' for float conversion assumes , is decimal point.
# temp = var.replace(',',"") # Or replace , with empty if , is a thousands delimiter.
fl = float(temp)
# if temp converts to a float return length of string is less than 7
return len(var) < 7
except ValueError:
return var == "" # If it doesn't convert to a float only accept an empty string.
vcmd = (root.register(validatecontent), '%P') # '%P' passes the whole new string to validate content.
entry = Entry(root, validate='key', validatecommand=vcmd) # Validate on key only.
entry.pack()
root.mainloop()
There may well be better validation functions involving regular expressions. This is reasonably easy to follow though. The entry can still be linked to a StringVar if required. It's not required to do the validation though.

How can I have a Tkinter program scan a text box for inputs in real time?

Ultimately I want to make a small program with a text box where you have to type in the first 50 or so digits of Pi. What I want is for nothing to happen if the user types the correct characters, but I want something to flash red if they input the wrong character. For example, if the user types "3.1", nothing happens but the text showing up in the text box, but if they then type the wrong number, like "3.15", I want something to flash red.
from tkinter import *
def input(event):
inp = (ent.get('1.0', END))
if inp == '3':
print(inp)
else:
print(('--') + (inp))
root = Tk()
root.title('pi, okay')
root.geometry('425x50')
ent = Text(root, width = 50, height = 1)
ent.bind('<KeyRelease>', input)
ent.pack()
mainloop()
What I think SHOULD happen with this is for the console to print "3" IF the user inputs a "3", and for the console to print "--(whatever else the user would have typed)" if it is not a 3. But what actually happens is that the program will print "--(input)" no matter what.
You can use something like this if you need only one line of Input:
var = StringVar()
ent = Entry(root, width=50, textvariable=var)
def check_value(var, ent, *args):
pi = "3.1415"
if not pi.startswith(var.get()):
print("wrong input")
ent.config(fg="red")
else:
ent.config(fg="black")
var.trace('w', lambda *args: check_value(var, ent, *args))
ent.pack()
Here, var.trace() will call function check_value everytime when user types anything in Entry widget. You can add you logic there to verify the input value and change UI(or print logs) based on verification result.

How to use .get() within a function. Python

from Tkinter import *
import random
def Factorer(a,b,c):
while True:
random_a1=random.randint(-10,10)
random_a2=random.randint(-10,10)
random_c1=random.randint(-10,10)
random_c2=random.randint(-10,10)
if random_a1==0 or random_a2 == 0 or random_c1 == 0 or random_c2 == 0:
pass
elif (random_a1*random_c2) + (random_a2*random_c1) == b and random_a1/random_c1 != random_a2/random_c2 and random_a1*random_a2==a and random_c1*random_c2==c:
break
print "y=(%dx+(%d))(%dx+(%d))" % (random_a1,random_c1,random_a2,random_c2)
root = Tk()
buttonSim1 = Button(root, text="Convert", command=lambda: Factorer(enterA.get(),enterB.get(),enterC.get()))
buttonSim1.grid(row=2, column=3)
enterA = Entry(root)
enterA.grid(row=1, column=1)
enterB = Entry(root)
enterB.grid(row=1, column=2)
enterC = Entry(root)
enterC.grid(row=1, column=3)
root.mainloop()
How can I get this code to run, every time I click the button It just crashes.
It works however if I remove the .get() and just insert numbers.
Thanks in advance
You are comparing strings to ints, you would need to cast a,b and c to int:
Tkinter.Button(root, text="Convert", command=lambda: Factorer(int(enterA.get()),int(enterB.get()),int(enterC.get())))
The root of the problem is that you're comparing strings to integers, so your infinite while loop never finishes. That is why the program hands and has to be force-quit.
The best solution is to have your button call a function that gets the data, formats it to the proper value, and then calls the function to do the work. Trying to squeeze all of that into a lambda makes for a program that is hard to debug.
For example:
def on_button_click():
a = int(enterA.get())
b = int(enterB.get())
c = int(enterC.get())
result = Factorer(a,b,c)
print(result)
Tkinter.Button(..., command=on_button_click)
By using a separate function, it gives you the opportunity to add print statements or pdb breakpoints so you can examine the data as it is running. It also makes it easier to add try/catch blocks to handle the case where the user didn't enter valid numbers.

Categories

Resources