How to ask user for integer input using Python tkinter - python

I need to ask a user for an integer value and tried a=n.get() and then a=int(a) but it doesn't work as expected. Here the code I used:
def selectparamter():
window3= Tk()
window3.title('choosing parameters ')
window3.resizable(False,False)
a_label = Label(window3, text = 'Select parameter', font=('calibre',10, 'bold'))
n = Entry(window3)
string_answer = n.get()
a= int(string_answer)
sub_btn=Button(window3,text = 'Submit', command =nrmltest )
sub_btn.grid(row=2,column=1)
a_label.grid(row=0,column=0)
n.grid(row=0,column=1)
window3.mainloop()
return a
How can I get the right integer value input from user in Python tkinter?

def selectparamter():
window3= Tk()
window3.title('choosing parameters ')
window3.resizable(False,False)
a_label = Label(window3, text = 'Select parameter', font=('calibre',10, 'bold'))
n_var = IntVar()
n = Entry(window3, textvariable=n_var)
a = n_var.get()
sub_btn=Button(window3,text = 'Submit', command =nrmltest )
sub_btn.grid(row=2,column=1)
a_label.grid(row=0,column=0)
n.grid(row=0,column=1)
window3.mainloop()
return a
For this code, IntVar class of tkinter was used to give value to "textvariable" attribute of widget. For more info, press here.
This can return the value of Entry widget as class but it will throw exception if string is given in the widget.
The value of 'a' seems to have been called right after widget creation. so, now with no text in widget, it will not perform properly.

Here you are ("If anybody knows how to solve this pls answer"):
from tkinter import Tk, Label, Entry, Button, IntVar
def selectparameter():
def getValueFromUser():
window3.quit()
window3= Tk()
window3.title('Choosing Parameters ')
window3.resizable(False, False)
a_label = Label(window3, text = 'Provide an integer value: ', font=('calibre',10, 'bold'))
n_var = IntVar()
n_var.set('')
n = Entry(window3, textvariable = n_var)
n.focus_set()
sub_btn=Button(window3, text='Submit', command = getValueFromUser )
sub_btn.grid(row=2,column=1)
a_label.grid(row=0,column=0)
n.grid(row=0,column=1)
window3.mainloop()
a = n_var.get()
return a
print(selectparameter())
BUT ... tkinter comes with a method which is both simpler and also better suited to get an integer input from user as it checks the user input and asks the user again in case of detected non-integer value:
from tkinter import Tk, simpledialog
root=Tk()
root.withdraw()
intUserInput = simpledialog.askinteger(title="askinteger", prompt="integerInputPlease")
root.destroy()
print(intUserInput)

Related

How to correctly use a tkinter error message box to wait until user input meets requirement?

I'm trying to use tkinter message boxes in a way so that if a user provides an invalid entry, an error message box appears and, after selecting "okay," they have the opportunity to provide a new entry. However, no subsequent calculations should take place until the entry is valid.
In this simple example, the user is asked to input a positive number, which is then doubled. In the first portion of the script, I've included code to ensure the user cannot enter letters or special symbols. Then I use an if-then to double my number if it is positive and produce an error message box if it isn't. Of course, there's nothing here as of yet that suspends the calculation until the input is valid. This is where I'm struggling.
from tkinter import Tk, Label, Entry, Button, messagebox
import re
def validate(string):
regex = re.compile(r"(\+|\-)?[0-9.]*$")
result = regex.match(string)
return (string == ""
or (string.count('+') <= 1
and string.count('-') <= 1
and string.count('.')<=1
and result is not None
and result.group(0) != ""))
def on_validate(P):
return validate(P)
window = Tk()
window.title("My Window")
window.geometry('800x800')
window.configure(bg='lightgrey')
input_label=Label(window,bg='lightgray',text="Enter positive number:")
input_label.grid(row=0, column=0,padx=10, pady=10)
# Get input and test for valid characters
entry = Entry(window, validate="key",width=20)
vcmd = (entry.register(on_validate), '%P')
entry.config(validatecommand=vcmd)
entry.grid(row=0,column=1,padx=10,pady=10)
output_label=Label(window,width=20)
output_label.grid(row=1, column=0,padx=10, pady=10)
def _compute():
input=float(entry.get())
if input<=0:
messagebox.showerror("Error","Input must be positive!")
# What can I do here to suspend the process until my input is valid?
else:
input=float(entry.get())
output_label.configure(text=str(2*input))
compute_button = Button(master=window, text="Compute",bg='lightgray',command=_compute)
compute_button.grid(row=2, column=0,padx=10, pady=10)
def _quit():
window.quit()
window.destroy()
quit_button = Button(master=window, text="Quit", bg='lightgray',command=_quit)
quit_button.grid(row=2, column=1,padx=10, pady=10)
window.mainloop()

How to tell user to only use integers if they input string in Python / Tkinter?

What would be the best way to give an error and tell the user to only input numbers if they type letters as an input? Code that doesn't work:
if self.localid_entry.get() == int(self.localid_entry.get():
self.answer_label['text'] = "Use numbers only for I.D."
The variable is obtained in Tkinter with:
self.localid2_entry = ttk.Entry(self, width=5)
self.localid2_entry.grid(column=3, row=2)
The best solution is to use the validation feature to only allow integers so you don't have to worry about validation after the user is done.
See https://stackoverflow.com/a/4140988/7432 for an example that allows only letters. Converting that to allow only integers is trivial.
Bryan has the correct answer, but using tkinter's validation system is pretty bulky. I prefer to use a trace on the variable to check. For instance, I can make a new type of Entry that only accepts digits:
class Prox(ttk.Entry):
'''A Entry widget that only accepts digits'''
def __init__(self, master=None, **kwargs):
self.var = tk.StringVar(master)
self.var.trace('w', self.validate)
ttk.Entry.__init__(self, master, textvariable=self.var, **kwargs)
self.get, self.set = self.var.get, self.var.set
def validate(self, *args):
value = self.get()
if not value.isdigit():
self.set(''.join(x for x in value if x.isdigit()))
You would use it just like an Entry widget:
self.localid2_entry = Prox(self, width=5)
self.localid2_entry.grid(column=3, row=2)
Something like this:
try:
i = int(self.localid_entry.get())
except ValueError:
#Handle the exception
print 'Please enter an integer'
""" Below code restricts the ttk.Entry widget to receive type 'str'. """
import tkinter as tk
from tkinter import ttk
def is_type_int(*args):
item = var.get()
try:
item_type = type(int(item))
if item_type == type(int(1)):
print(item)
print(item_type)
except:
ent.delete(0, tk.END)
root = tk.Tk()
root.geometry("300x300")
var = tk.StringVar()
ent = ttk.Entry(root, textvariable=var)
ent.pack(pady=20)
var.trace("w", is_type_int)
root.mainloop()

Clear text from tkinter entry widget

I am using Tkinter entry widgets to allow users to input text to a GUI. The entry widgets have default text which I would like to clear with a single button press. I have the following code:
from Tkinter import *
def delete_entries(fields):
for field in fields:
field.delete(0,END)
def UserInput(status,name):
optionFrame = Frame(root)
optionLabel = Label(optionFrame)
optionLabel["text"] = name
optionLabel.pack(side=LEFT)
var = StringVar(root)
var.set(status)
w = Entry(optionFrame, textvariable= var)
w.pack(side = LEFT)
optionFrame.pack()
if __name__ == '__main__':
root = Tk()
fields = 'ExperimentNumber', 'OutputFileName', 'npts1', 'block1'
ExperimentNumber = UserInput("1", "Experiment number")
OutputFileName = UserInput("output.txt", "Output file name")
npts1 = UserInput("1000", "Number of points")
block1 = UserInput("8", "Block size")
Delete_button = Button(root, text = 'Clear all', command = delete_entries(fields))
Delete_button.pack()
I have tried creating fields with the list of variables that I want to delete (as above) and iterating over this in the function delete_entries(), however this returns an error because the entries in fields are strings. I have tried replacing fields with fields = ExperimentNumber for example, but this returns an error because ExperimentNumber hasn't yet been defined. Finally I tried putting ExperimentNumber within the delete function i.e.
def delete_entries():
ExperimentNumber.delete(0,End)
but this doesn't work because ExperimentNumber has the attribute NoneType (I don't understand why this is, because the delete_entries() function isn't called until after the ExperimentNumber Entry widget is created via the function UserInput). How can I go about deleting all the text in the Entry widgets? I have about 20 of these in my actual code and would like the user to be able to clear all the fields with one button press.
You are on the right track but you missed two little things. I added those two in your code and tried to explain with comments.
from Tkinter import *
def delete_entries():
for field in fields:
field.delete(0,END)
def UserInput(status,name):
optionFrame = Frame(root)
optionLabel = Label(optionFrame)
optionLabel["text"] = name
optionLabel.pack(side=LEFT)
var = StringVar(root)
var.set(status)
w = Entry(optionFrame, textvariable= var)
w.pack(side = LEFT)
optionFrame.pack()
return w
#this return is crucial because if you don't return your widget's identity,
#you can not use them in another function
if __name__ == '__main__':
root = Tk()
ExperimentNumber = UserInput("1", "Experiment number")
OutputFileName = UserInput("output.txt", "Output file name")
npts1 = UserInput("1000", "Number of points")
block1 = UserInput("8", "Block size")
#you are saying it does not work because of they are strings.
#then don't assign strings to fields. assign variables.
fields = ExperimentNumber, OutputFileName, npts1, block1
#since fields is defined in global scope, you don't need to use it as parameter
Delete_button = Button(root, text = 'Clear all', command = delete_entries)
Delete_button.pack()
root.mainloop()

Updating Text In Entry (Tkinter)

The piece of code below takes input from user through a form and then returns the input as multiplied by 2. What I want to do is, when a user types a number (for example 5) and presses the "Enter" key on keyboard or clicks on "Calculate" button, the place where he entered the number "5" should also display 10, besides the place immediately below. Normally, the form keeps the number entered , but the place right below it gets updated and displays 10 (let us say you have entered 5)
How can I also update the form place?
(Please let me know if my question is unclear, so I can better explain myself.)
from tkinter import *
def multiplier(*args):
try:
value = float(ment.get())
result.set(value * 2)
except ValueError:
pass
mGui = Tk()
mGui.geometry("300x300+300+300")
ment = StringVar()
result = StringVar()
mbutton = Button (mGui, text = "Calculate", command = multiplier)
mbutton.pack()
mEntry = Entry(mGui, textvariable = ment, text="bebe")
mEntry.pack()
mresult = Label(mGui, textvariable = result)
mresult.pack()
You can use Entry's delete and insert methods.
from tkinter import *
def multiplier(*args):
try:
value = float(ment.get())
res = value *2
result.set(res)
mEntry.delete(0, END) #deletes the current value
mEntry.insert(0, res) #inserts new value assigned by 2nd parameter
except ValueError:
pass
mGui = Tk()
mGui.geometry("300x300+300+300")
ment = StringVar()
result = StringVar()
mbutton = Button (mGui, text = "Calculate", command = multiplier)
mbutton.pack()
mEntry = Entry(mGui, textvariable = ment, text="bebe")
mEntry.pack()
mresult = Label(mGui, textvariable = result)
mresult.pack()
The StringVars you update via the set method, which you're doing in the multiplier function. So you question is how to trigger the call the multiplier when the user presses enter, you can use:
mGui.bind('<Return>', multiplier)
Do you also want to change the text in the Entry? The question is a bit unclear. You can do that via ment.set as well.

Python: Tkinter message Box - Error Handling

I'm looking to use the Tkinter message windows as an error handler. Basically just saying you can only input "x,y,z"
It's being used on a program that asks the user for the input, Any integers that are => 0 and =<100 are accepted. At the moment it's working but only displays it on a label.
Can anyone suggest anything i can use to input a tkinter error window? Also any idea how i can limit the input to just Integers?
Below is the add function that once the user inputs a number and click's add, it fires this function.
If i haven't explained this well then please advise me and i'll try to expand on it.
def add():
try:
value = int(MarkEnt.get())
assert 0 <= value <= 100
mark.set(value)
exammarks.append(value)
ListStud.insert(len(exammarks),value)
except AssertionError:
error1.set("Please only input whole numbers from 0 to 100")
errorLbl.grid()
You can use the tkMessageBox module to show error boxes.
from Tkinter import *
import tkMessageBox
def clicked():
tkMessageBox.showerror("Error", "Please only input whole numbers")
root = Tk()
button = Button(root, text = "show message box", command = clicked)
button.pack()
root.mainloop()
Also any idea how i can limit the input to just Integers?
You can use validatecommand to reject input that doesn't fit your specifications.
from Tkinter import *
def validate_entry(text):
if text == "": return True
try:
value = int(text)
except ValueError: #oops, couldn't convert to int
return False
return 0 <= value <= 100
root = Tk()
vcmd = (root.register(validate_entry), "%P")
entry = Entry(root, validate = "key", validatecommand=vcmd)
entry.pack()
root.mainloop()

Categories

Resources