Updating Text In Entry (Tkinter) - python

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.

Related

How to ask user for integer input using Python tkinter

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)

tkinter: checkbox doesn't update in for-loop [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 1 year ago.
I'm stuck on the following problem. With a for-loop, I want to make a few checkboxes that automatically update a label stating whether the checkbox is ticked or not. However, it gives the wrong results (it always says that the checkboxes are ticked, whether this is the case or not; noteworthy is the fact that the checkboxes are unticked by default), see here how the GUI looks like (including error). The IntVars corresponding with the checkboxes are working correctly, as can be seen when ticking at least one of the checkboxes and pressing a button whose function is to read the checkboxes. See also the following code:
import tkinter as tk
top = tk.Tk()
n_passes = 3
checkbox_var = [0] * n_passes
checkbox = [0] * n_passes
def tick_passes(i): # update label saying if checkboxes are ticked
if checkbox_var[i].get == 0:
label = tk.Label(top, text = f"pass #{i} not ticked")
else:
label = tk.Label(top, text = f"pass #{i} ticked")
label.grid(row = 1, column = i)
def check_checkbox_var(): # check whether checkbox_var[i] is updated
for i in range(n_passes):
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
for i in range(n_passes):
checkbox_var[i] = tk.IntVar() # turn on/off certain passes
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
checkbox[i] = tk.Checkbutton(top, text = f"Tick pass {i}", variable =
checkbox_var[i], command = tick_passes(i))
checkbox[i].grid(row = 0, column = i, sticky=tk.W)
var_button = tk.Button(top, text = "Check checkbox_var", command =
check_checkbox_var).grid(row = 2, column = 0) # check whether checkbox_var[i] is updated
top.mainloop()
Could somebody help me with updating the labels? If there is another way to fix this issue, e.g. with buttons to be pressed instead of checkbuttons to be ticked, that would also work for mee.
i is always 2 because you're actually not running any loop after mainloop is started.
The following kind of works but you need to change something about the labels, because right now all labels are just added on top of each other. You should create them once and then just update the text but I'll leave that part for you.
import tkinter as tk
top = tk.Tk()
n_passes = 3
checkbox_var = [0] * n_passes
checkbox = [0] * n_passes
def tick_passes(): # update label saying if checkboxes are ticked
for i in range(n_passes):
if checkbox_var[i].get() == 0:
label = tk.Label(top, text = f"pass #{i} not ticked")
else:
label = tk.Label(top, text = f"pass #{i} ticked")
label.grid(row = 1, column = i)
def check_checkbox_var(): # check whether checkbox_var[i] is updated
for i in range(n_passes):
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
for i in range(n_passes):
print(i)
checkbox_var[i] = tk.IntVar() # turn on/off certain passes
print(f"checkbox_var[i].get() = {checkbox_var[i].get()}")
checkbox[i] = tk.Checkbutton(top, text = f"Tick pass {i}", variable =
checkbox_var[i], command = tick_passes)
checkbox[i].grid(row = 0, column = i, sticky=tk.W)
var_button = tk.Button(top, text = "Check checkbox_var", command =
check_checkbox_var).grid(row = 2, column = 0) # check whether checkbox_var[i] is updated
top.mainloop()

How to validate text box inputs in real-time

Its an application which asks a math problem and user inputs answer in a textbox as integers, and a button submitbtn verifies if its right or wrong.
I binded a keyboard key f to the function that runs on pressing button submitbtn, which works fine, but the key f gets added to the textbox after user's answer before it submits and gives it as a wrong answer.
Text Box
text_Input = StringVar
txtbox = Entry(font=('arial',20, BOLD), textvariable=text_Input)
txtbox.grid(columnspan = 2, row = 3, pady = 20)
txtbox.focus_set()
Submit Button
submitbtn = Button(text="Submit", padx=10, pady=10, command=lambda:submit(txtbox.get(), y))
Submit Function
def submit(z, y):
global correct_answer, wrong_answer, submitbtn
y=str(y)
if z==y:
correct_answer+=1
lbl2.configure(text=correct_answer)
else:
wrong_answer+=1
lbl4.configure(text=wrong_answer)
submitbtn.config(state="disabled")
Binding
game.bind('f', lambda event: submit(txtbox.get(), y))
#"game" is the name of Tk()
#submit is the function linked to submitbtn
#This works well if I bind it to <Return> (Enter Key)
Actual Output:
5+8
User enters: 13
Presses 'f' to submit answer
Answer processed: 13f
Is there a way to process textbox inputs in real-time to make sure every character entered is an integer? If user enters anything except 0-9, I want it to note nothing in the textbox.
Also, I disable the submitbtn after it is pressed once, but pressing f repeatedly keep incrementing the correct_answer variable. Is there a way to bind the key to the submitbtn which in turn will call the function submit, instead of directly linking the key f to submit function?
For your first question, there are two ways to do it. Either you use the trace method on your StringVar, or use validcommand on your entry. You can read up the details on how to use both methods here and here
import tkinter as tk
root = tk.Tk()
# Use trace method on your StringVar
text_Input = tk.StringVar() # note that it is StringVar() with ()
txtbox = tk.Entry(font="Arial 20 bold",textvariable=text_Input)
txtbox.grid(columnspan = 2, row = 3, pady = 20)
def trace_method(*args):
if text_Input.get().isdigit():
pass
else:
text_Input.set(text_Input.get()[:-1])
text_Input.trace("w",trace_method)
# Use validatecommand attribute of entry widget
def onValidate(S):
if S.isdigit():
return True
else:
return False
vcmd = (root.register(onValidate),"%S")
txtbox2 = tk.Entry(font="Arial 20 bold",validate="key",validatecommand=vcmd)
txtbox2.grid(columnspan = 2, row = 4, pady = 20)
root.mainloop()
For your second question, I can't fully understand what you are trying to achieve, but if the problem lies with the binding with key f, i suppose you can simply call game.unbind('f') in your submit function.

Python How to use entry text value in another function using GUI

I am using tkinter GUI. Created GUI, Now at one of my GUI ask Input value and I need to display that Input Value in another function and print that value.
Code is as below:
def EventOnBtnIO():
#some commutation
ForceNumericItem() #Called the function to open the new GUI
request = 'FF'+Value
print request
return
This is my GUI which consists of entry box and buttons
def ForceNumericItem():
global Subtop
Subtop = Toplevel(top)
Subtop.geometry("350x110+500+200")
Subtop.title("Force Numeric Items")
Subtop.grab_set()
frame = Frame(Subtop,width=15, height=200,bd = 1)
frame.pack(fill = 'both',padx=3, pady=3)
# frame.config(relief=RIDGE)
global entry2
global entrytext2
entrytext2 = IntVar()
entry2 = Entry(frame,textvariable=entrytext2, width = 45)
entry2.pack(padx = 5, pady = 5)
entry2.focus_set()
entry2.selection_range(0, END)
topButtonShow = Button(frame, text = 'OK',command = ForceValue,width = 10)
topButtonBack = Button(frame, text = 'Cancel',command = okclose,width = 10)
topButtonShow.pack(side = LEFT,padx=45,pady=5)
topButtonBack.pack(side = RIGHT,padx=45,pady=5)
return
After OK click, it should take the Value and display in my EventOnBtnIO function
def ForceValue():
global Value
Value = int(entrytext2.get())
print Value
Subtop.destroy()
top.deiconify()
return
I think it is related to local or global varibale, but not able to fix it. Getting value now
FF
Expected value
FF + Value
The function in which you create your popup window returns before the user has input a number in it. To fix this, you could use the .wait_window() method:
def EventOnBtnIO():
ForceNumericItem()
top.wait_window(Subtop)
request = 'FF'+str(Value)
print request

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()

Categories

Resources