I am Python coder and got stuck in a question that "How to check input in textbox of tkinter python". The problem is that it is not giving output on writing this code .
def start(event):
a = main.get(1.0,END)
if a == 'ver':
print('.....')
main = Text(root)
main.pack()
root.bind('<Return>',start)
We can do this by get() method:
from tkinter import *
a=Tk()
def check():
print(x.get('1.0',END)[:-1])
x=Text(a)
b=Button(a,text='Check',command=check)
x.pack()
b.pack()
a.mainloop()
The text widget guarantees that there is always a trailing newline. When you do get(1.0,END) you're getting that trailing newline even if the user doesn't enter a newline.
If you want to get exactly what the user entered, use get("1.0", "end-1c"). That will get all of the characters up to the end, minus one character.
Note: text indexes are strings of the form line.character. Your code is using the floating point value 1.0 which is incorrect. It works fine in some cases, but it won't work in all. You should always use a string rather than a float for text indexes.
from tkinter import *
from threading import Thread
root = Tk()
def check():
while True :
a = main.get(1.0,END)[:-1]
if a == 'ver':
print('.....')
main = Text(root)
main.pack()
Thread(target=check).start()
root.mainloop()
You should write something like
def start(event):
t = var.get()
if t == 'something':
pass
var = StringVar()
e = Entry(master, textvariable=var)
e.pack()
e.bind(bind('<Return>',start)
Related
I am trying to work my way through Tkinter and this is a part of my code:
FirstName = Label(canvas, text="First Name")
FirstName.configure(width=30, bg="white", fg="black", border=10)
FirstName = canvas.create_window(330, 130, anchor = CENTER, window=FirstName)
FName_Entry = Entry(canvas)
canvas.create_window(850, 145, window=FName_Entry, height=35, width=300)
As you can see this is an entry widget for users to enter their first name.
how can I validate this to only accept string (letters) and if they try to enter integers, symbols or basically anything that is not a letter, it should display a message on the side of the widget urging users to enter a valid name.
I tried to check online but most of them are using classes and I am not used to classes as of yet and am new to Tkinter. other examples explain how to limit entry to integers so I am a bit confused here.
Thanks for helping!
Here is a small snippet to actually make you understand better
from tkinter import *
from tkinter import messagebox
root = Tk()
def check():
sel = e.get()
if not sel.isalpha():
messagebox.showerror('Only letters','Only letters are allowed!')
e = Entry(root)
e.pack(pady=10)
b = Button(root,text='Click Me',command=check)
b.pack(padx=10,pady=10)
root.mainloop()
Here we are checking if sel.isalpha() returns False or not, if it does, then show a messagebox saying only letters are allowed. Simple as that.
Do let me know if any errors. Happy coding
Here is more on isalpha() method
Cheers
You can use list in which you can store the letter which is to be accepted.
Then check the each letter of the input with the element in the list.
If any character not found from the input in the list(acceptable character) then it is invalid input.
# acceptable character list
accepted_characters = ['a', 'b', 'c',.....'z', 'A', 'B', 'C',...'Z']
# input from the tkinter entry widget
inp = "hello"
for i in inp:
if i not in accepted_characters:
print('Invalid data.')
Another way is using RegEx module which is built-in module. But I am not too familiar with RegEx.
i am facing a problem. I'm runnig this code.
import tkinter as tk
root = tk.Tk()
def check():
if len(e.get().split("a")) > 1:
print("contains a")
e = tk.Entry(frame1)
e.grid(row=4,column=1,columnspan=2,padx = (10,10), pady=(5,10), sticky="w e")
e.bind("<Key>",check)
when i type "a" to the entry I wont get nothing printed. I'll get the result by tiping a second character. I think that it happens because the function gets executed before the content has actualy changed. I tried to add a timer on the beginning of the function but it does nothing.
I want get the result by entering the first "a". What should I do?
I think that it happens because the function gets executed before the content has actualy changed.
You're right. If you want the callback to be able to see the character you just typed, you should create a StringVar and bind to that instead of binding to a "<Key>" event on the widget.
import tkinter as tk
frame1 = tk.Tk()
def check(*args):
if "a" in s.get():
print("contains a")
s = tk.StringVar()
e = tk.Entry(frame1, textvariable=s)
s.trace("w", check)
e.grid(row=4,column=1,columnspan=2,padx = (10,10), pady=(5,10), sticky="w e")
frame1.mainloop()
I'm somewhat new to Tkinter with minor Python experience so I hope the answer's not too obvious, I've attempted to search for an answer but couldn’t find anything helpful. Essentially I'm trying to build a program where (as a placeholder test for now), if a user enters 1 in the entry field and hits submit, a window appears telling them they typed 1, otherwise they're told to type 1. If my understandings correct, this should work:
from Tkinter import *
#-----------------------------------------------------------
import tkMessageBox
root = Tk()
#-----------------------------------------------------------
root.title('Payroll System')
#-----------------------------------------------------------
def on_printtext(root):
global entryform
string = entryform.get()
if string == 1:
tkMessageBox.showinfo('You typed 1')
elif string != 1:
tkMessageBox.showinfo('Please type 1')
#-----------------------------------------------------------
entryform = Entry(root)
entryform.pack()
submit = Button(root, text="Submit", command=on_printtext)
submit.pack()
root.mainloop()
However when I try to run it and enter 1 in the entry form after hitting submit I get this:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in call
return self.func(*args)
TypeError: on_printtext() takes exactly 1 argument (0 given)
The issue is that tkinter is trying to call the function registered as the command for the button without any arguments, but your function has 1 argument - root without any default variable, and hence that is causing the issue you are having.
Also some other issues in your code -
Entry.get() returns a string, but you are trying to compare that against an integer , it would never be equal, so even if you enter 1 it would still show Please type 1 .
When you do - tkMessageBox.showinfo('You typed 1') - you are actually setting the title to You typed 1 , not the actual message. For the functions of tkMessageBox, the first argument is the title, and the second argument is the message. If you want that as the message, set it as themessage` using keyword argument. Example -
tkMessageBox.showinfo(message='You typed 1')
Example code that works -
from Tkinter import *
import tkMessageBox
root = Tk()
root.title('Payroll System')
def on_printtext():
global entryform
strng = entryform.get()
if strng == '1':
tkMessageBox.showinfo(message='You typed 1')
else:
tkMessageBox.showinfo(message='Please type 1')
entryform = Entry(root)
entryform.pack()
submit = Button(root, text="Submit", command=on_printtext)
submit.pack()
root.mainloop()
If you are using Python 3.x, the code above does not work since tkMessageBox has been changed to messagebox.
Here's the modified code:
from tkinter import * # modif 1 Tkinter with minus t !
import tkinter.messagebox # modif 2:tkMessageBox no longer valid
root = Tk()
root.title('Payroll System')
def on_printtext():
global entryform
strng = entryform.get()
if strng == '1':
tkinter.messagebox.showinfo(message='You typed 1') # modif 3
else:
tkinter.messagebox.showinfo(message='Please type 1') # modif 4
entryform = Entry(root)
entryform.pack()
submit = Button(root, text="Submit", command=on_printtext)
submit.pack()
root.mainloop()
I've been having a lot of difficulties with this code, and I just can't find any solutions, I will post my code below.
from tkinter import *
a = []
class test(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title('testing')
self.pack(fill=BOTH, expand=1)
self.d = DoubleVar()
self.d.set('None')
def grab():
b = ent.get()
a.append(b)
c = [s.strip('qwertyuiopasdfghjklzxcvbnm') for s in a]
self.d.set(c[-1])
if c[-1] == '':
self.d.set('None')
ent = Entry(self)
ent.grid(row=0, column=0)
but = Button(self, text='Get', command=grab)
but.grid(row=1, column=0)
Label(self, textvariable=self.d).grid(row=2, column=0)
root = Tk()
app = test(root)
root.mainloop
I guess my objective is to be able to ignore, or delete the letters that are placed inside of the entry box, as you can see, I've used the strip method, but it doesn't work the way I would like it to. If anyone could offer some advice, or a code, or link me to a question that I overlooked, that would be amazing, and I would be greatful.
EDIT: It already clears letters before and after, but nothing in between
A validator would be the correct pattern to solve this problem. Interactively validating Entry widget content in tkinter has an implementation in tkinter that you should be able to use.
A little bit of lambda should do the trick
a = "123a3456b"
filter(lambda '0' <= x <= '9', a)
print a
"1233456"
You're getting letters inside the numbers because you're putting the string into a list first.
strip() removes leading and trailing characters, so if you have a string: aaa000bbb111ccc, stripping letters from it will only remove the outer-most letters. If you split the string, however, and then strip letters from each element of the stripped string, you'll effectively remove all the letters. Then, you can join() the remaining parts of the list together to get back to your string. Consider this example:
>>> import string # string.ascii_letters returns a string of all letters (upper and lower), just easier than typing them
>>> def check(x):
return ''.join([char.strip(string.ascii_letters) for char in x])
>>> var = 'aaa000bbb111ccc'
>>> var_as_list = [var]
>>> check(var)
'000111'
>>> check(var_as_list)
'000bbb111'
So, c should be:
c = ''.join([s.strip('qwertyuiopasdfghjklzxcvbnm') for s in b.get()])
You should also consider some further validation, if you want the field to only contain floats. Here's one method to trace any changes to a StringVar() instance and restrict changes to it to only being numbers and periods:
from tkinter import *
import string
def check(*args):
# make a 'whitelist' of allowable characters
whitelist = string.digits + '.'
# set var to its current value - any characters not in whitelist
var.set(''.join([i for i in var.get() if i in whitelist]))
root = Tk()
var = StringVar()
var.set('0.0')
Entry(root, textvariable=var).grid(row=0, column=0)
Label(root, textvariable=var).grid(row=1, column=0)
var.trace('w', check) # if var changes, call check()
mainloop()
a clean way to do this is simply:
filter(lambda s: not str.isalpha(s), data)
My program should check if the first three letters of the input word are similar to a predefined word.
I've made a GUI with Tkinter and want to get the letters of the input field.
Somehow I can't implement it in like I would do without Tkinter.
That's how I do it just for the shell:
text = raw_input('Enter a word: ')
if (text[0] + text[1] + text[2] == 'sag'):
print "sagen"
else:
print "error"
So, when I input the word "sagst" it checks the first three letters and should put out "sagen". Works fine.
I learned that e.g. inputfield.get() gets the input of the entry "inputfield".
But how can I check the first letters of that "inputfield"?
A small selection:
from Tkinter import*
root = Tk()
def check():
if (text[0] + text[1] + text[2] == 'sag'):
print "True"
else:
print "False"
inputfield = Entry(root)
inputfield.pack()
but = Button(root,text='Check!', command = check)
but.pack()
text = inputfield.get()
root.mainloop()
Does not work...
I hope you can understand my question and will answer soon. (Sorry for my bad english and my bad Python skills) ;-)
Thanks!
Your check function will have to retrieve the textfield after the button has been pressed:
def check():
text = inputfield.get()
print text.startswith('sag')
I've changed your test a little, using .startswith(), and directly printing the result of that test (print will turn boolean True or False into the matching string).
What happens in your code is that you define inputfield, retrieve it's contents (obviously empty), and only then show the TKInter GUI window by running the mainloop. The user never gets a chance to enter any text that way.
You can also check this without the need for a button (Now it will check whenever the user presses "Enter"):
from Tkinter import *
root = Tk()
def check(*event):
text = inputfield.get()
print text.startswith('sag')
inputfield = Entry(root)
inputfield.bind('<Return>',check)
inputfield.pack()
root.mainloop()
You can also do other things to have your widget validate the entry as you type. (The link is old, but it also points to newer features that allow you to do this without subclassing).
You're not actually putting the value in the input field into the text variable.
I renamed the value from text to input_text because it was confusing to me. I also changed from using text[0] + text[1] + text[2] to using startswith(). This will keep you from getting IndexErrors on short strings, and is much more pythonic.
from Tkinter import*
root = Tk()
def check():
input_text = inputfield.get()
if input_text.startswith('sag'):
print "True"
else:
print "False"
inputfield = Entry(root)
inputfield.pack()
input_text = inputfield.get()
print input_text # Note that this never prints a string, because it only prints once when the input is empty.
but = Button(root, text='Check!', command=check)
but.pack()
root.mainloop()
The key change is that the check function needs to actually get the value in the inputfield.
Here is a version which uses an Entry widget which validates its contents as the user types (so the user does not have to click a button or even press Return).
import Tkinter as tk
class MyApp(object):
'''
http://effbot.org/zone/tkinter-entry-validate.htm
http://effbot.org/tkinterbook/entry.htm
http://www.tcl.tk/man/tcl8.5/TkCmd/entry.htm#M-validate
'''
def __init__(self, master):
vcmd = (master.register(self.validate),
'%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
self.entry = tk.Entry(master, validate = 'key',
validatecommand = vcmd)
self.entry.pack()
self.entry.focus()
def validate(self, action, index, value_if_allowed,
prior_value, text, validation_type, trigger_type, widget_name):
dtype = {'0':'delete', '1':'insert', '-1':'other'}[action]
n = min(3, len(value_if_allowed))
valid = False
if dtype == 'insert':
if value_if_allowed[:n] == 'sag'[:n]: valid = True
else: valid = False
else: valid = True
print(valid)
return True
root = tk.Tk()
app = MyApp(root)
root.mainloop()