This question already has answers here:
Interactively validating Entry widget content in tkinter
(10 answers)
Closed 8 years ago.
I am trying to make a basic calculator in python tkinter. I made an entry box that user types his first number into. But then, what if someone enters in something other than numbers, but text? My question is, how to make that you can put only number to entry box, or how it can ignore normal letters.
By the way, my half-done code is here:
from tkinter import *
okno = Tk()
okno.title("Kalkulačka")
okno.geometry("400x500")
firstLabel = Label(text="Vaše první číslo").place(x=25, y=25)
firstInput = Entry(text="Vaše první číslo").place(x=130, y=25, width=140)
buttonplus = Button(text="+").place(x=130, y=75)
buttonminus = Button(text="-").place(x=165, y=75)
buttonkrat = Button(text="・").place(x=197, y=75)
buttondeleno = Button(text=":").place(x=237, y=75)
What I would do personally is run every user input through an integer verifying function before accepting it as input. Something simple like this:
def is_int(x):
try:
x = int(x)
return True
except:
return False
Related
This question already has answers here:
How can I schedule updates (f/e, to update a clock) in tkinter?
(8 answers)
Closed 1 year ago.
I am making a responce bot in python with tkinter. For that when user inputs something I will give answer.
I have not yet completed it. I wanted that the bot should answer after some-time so it looks very nice.
My code:-
import tkinter
from tkinter import Message, messagebox
from tkinter import font
from tkinter.constants import CENTER, LEFT, RIGHT, BOTTOM, TOP
from tkinter import scrolledtext
from typing import Sized
import time
window = tkinter.Tk()
window.geometry("370x500")
window.configure(bg="orange")
#variables
running = True
verdana_12 = ('Verdana', '12')
verdana_10 = ('Verdana', '10')
verdana_9 = ('Verdana', '9')
msg=tkinter.StringVar()
#messages
greetings = ["hi", "hello", "hey", "what's up!"]
questions = [
' 1. What is python?',
' 2. Where to ask questions if I get stuck?',
' 3. How can I get example questions and quizes related to python?'
]
#items inb gui
info_text = tkinter.Label(window, text="Chat", bg="orange", font=verdana_12)
info_text.pack(padx=20, pady=5)
text_1 = tkinter.Label(window, text="Type your message: ", font=verdana_9, bg="orange")
text_1.place(x=0, y=476)
input_area = tkinter.Entry(window, justify=LEFT, textvariable=msg, font=verdana_12, width=16)
input_area.focus_force()
input_area.place(x=135, y=476)
chat_area = scrolledtext.ScrolledText(window)
chat_area.pack(padx=20, pady=5)
chat_area.config(state = "disabled")
#define message
message = f"You: {input_area.get()}\n"
#functions
#def afterwards():
# mine_msg = message.lower().strip().split()[1]
# if 1 == mine_msg:
# reply("Bot: Python is an interpreted high-level general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant indentation. More info at https://en.wikipedia.org/wiki/Python_(programming_language)")
#
# elif 2 == mine_msg:
# reply("Bot: If you get stuck in python programming, go to stackoverflow.com where you can ask questions related to any programming language!")
#
# elif 3 == mine_msg:
# reply("Bot: You can get quizes related to python in w3schools.org and example questions in w3resource.org.")
def reply(reply_msg):
str(reply_msg)
the_reply = f"{reply_msg}\n" #input_area = where person types.
chat_area.config(state='normal')
chat_area.insert(tkinter.INSERT, the_reply)
chat_area.yview('end')
chat_area.config(state='disabled')
input_area.delete(0, 'end')
def check_msg():
global message
print('Message =', message.strip())
try:
mine_msg = message.lower().strip().split()[1]
if greetings[0] == mine_msg or greetings[1] == mine_msg or greetings[2] == mine_msg or greetings[3] == mine_msg:
reply("Bot: Hello, here's how I can help you")
for i in questions:
reply(i)
#afterwards()
else:
reply("Bot: Couldn't understand your message, please type 'hi', 'hello', 'hey' or 'what's up!' to get responce.")
except IndexError:
pass
def write():
global message
if len(input_area.get().split()) > 0:
message = f"You: {input_area.get()}\n" #input_area = where person types.
chat_area.config(state='normal')
chat_area.insert(tkinter.INSERT, message)
chat_area.yview('end')
chat_area.config(state='disabled')
input_area.delete(0, 'end')
check_msg()
else:
reply('Please type something.')
def print_it():
message = f"You: {input_area.get()}"
print(message)
#button_send
send_button = tkinter.Button(window, text="Send", command=write, font=verdana_10, bg="gray", fg="white", width=26, height=1)
send_button.pack(padx=20, pady=5)
window.mainloop()
It freezes everything for 0.5 instead I want it to freeze only the write() function. Any help please.
Thank you!
One way to achieve this would be to use the .after method from tkinter to delay the message from being replied to for a period of time.
i = "My Message"
window.after(1000,lambda i=i: reply(i))
This would call the reply function with the message "My Message" after 1000ms or 1 second.
The following code works for requesting input from a user through the Tkinter GUI and turning that input into a usable variable in the main script. However, any value that I put as the last in a list in the if statement (here "4") will hang and crash the program upon enter. This was also the case for "n" in a yes/no scenario. It also happens if I replace the if statement with a while not in [values] - the final value will crash the program. Is this just a quirk of Tkinter or is there something that I am missing?
import tkinter as tk
from tkinter import *
# get choice back from user
global result
badinput = True
while badinput == True:
boxwidth = 1
result = getinput(boxwidth).strip().lower()
if result in ['1', '2', '3', '4']:
badinput = False
# iterate through play options
if result == '1':
# Do Something
elif result =='2':
# Do Something
elif result =='3':
# Do Something
else:
# Do Something
def getinput(boxwidth):
# declaring string variable for storing user input
answer_var = tk.StringVar()
# defining a function that will
# get the answer and set it
def user_response(event):
answer_var.set(answer_entry.get())
return
answer_entry = tk.Entry(root, width = boxwidth, borderwidth = 5)
# making it so that enter calls function
answer_entry.bind('<Return>', user_response)
# placing the entry
answer_entry.pack()
answer_entry.focus()
answer_entry.wait_variable(answer_var)
answer_entry.destroy()
return answer_var.get()
In case anyone is following this question, I did end up solving my problem with a simple if statement within the callback. I can feed a dynamic "choicelist" of acceptable responses into the callback upon user return. If the answer is validated, the gate_var triggers the wait function and sends the program and user response back into the program.
'''
def getinput(boxwidth, choicelist):
# declaring string variable for storing user input
answer_var = tk.StringVar()
gate_var = tk.StringVar()
dumplist = []
# defining a function that will
# get the answer and set it
def user_response(event):
answer_var.set(answer_entry.get())
if choicelist == None:
clearscreen(dumplist)
gate_var.set(answer_entry.get())
return
if answer_var.get() in choicelist:
# passes a validated entry on to gate variable
clearscreen(dumplist)
gate_var.set(answer_entry.get())
else:
# return to entry function and waits if invalid entry
clearscreen(dumplist)
ErrorLabel = tk.Label(root, text = "That is not a valid response.")
ErrorLabel.pack()
ErrorLabel.config(font = ('verdana', 18), bg ='#BE9CCA')
dumplist.append(ErrorLabel)
return
global topentry
if topentry == True:
answer_entry = tk.Entry(top, width = boxwidth, borderwidth = 5)
else:
answer_entry = tk.Entry(root, width = boxwidth, borderwidth = 5)
# making it so that enter calls function
answer_entry.bind('<Return>', user_response)
# placing the entry
answer_entry.pack()
answer_entry.focus()
answer_entry.wait_variable(gate_var)
answer_entry.destroy()
return answer_var.get()
'''
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 2 years ago.
I want to make a calculator that adds 10 to the number using tkinter.
But I had to get the entry price in int format, so I used get method.
I keep getting the following error message. What's the problem?
from tkinter import *
window=Tk()
a=Entry(window)
a.pack()
b=a.get()
c=int(b)
result2=Label(window,text="")
result2.pack()
def Button_Press():
global c
result=c+10
result2.config(text=result)
button=Button(window,command=Button_Press())
button=pack()
window.mainloop()
Here's the error text.
c=int(b)
ValueError: invalid literal for int() with base 10: ''
ValueError: invalid literal for int() with base 10: ''
Has show you that the c is ''(a string which length is zero).The code seems to be int('').That's why it will raise exception.
Your code could be:
from tkinter import *
window = Tk()
a = Entry(window)
a.insert("end", "0") # just insert a str "0"
a.pack()
b = a.get()
c=int(b)
print(c)
result2 = Label(window, text="")
result2.pack()
def Button_Press():
result = c + 10
result2.config(text=result)
button = Button(window, command=Button_Press) # there is no "()"
button.pack() # not button = pack()
window.mainloop()
This question already has answers here:
Interactively validating Entry widget content in tkinter
(10 answers)
Closed 3 years ago.
I have an entry field in my tkinter GUI app. entry should only accept numbers including decimal points. I used a function to validate the entry. The problem is, it is not accepting decimal point(.) if there is a digit in front of it. (example 25.3 wont accept). if there is a point in the beginning, it is not accepting any number after that. Could anyone help me with this problem. and any suggestion to limit the maximum value in the entry field to 1000?
import tkinter as tk
def acceptNumber(inp):
if inp.isdigit():
return True
elif inp is "":
return True
elif inp is ".":
return True
else:
return False
win = tk.Tk()
reg = win.register(acceptNumber)
entryHere =tk.Entry(win)
entryHere.place(x=400, y=200)
entryHere.config(validate="key", validatecommand =(reg, '%P'))
win.mainloop()
This accepts valid decimal numbers not greater than 1000:
def acceptNumber(inp):
try:
return True if inp == '' else float(inp) <= 1000
except:
return False
>>> s='1234'
>>> s.isdigit()
True
>>> sdot = '1234.'
>>> sdot.isdigit()
False
Isn't this your problem. isdigit() means digits only.
I am trying to create a program which only allows you to write a certain amount of characters as a prompt while using a text box. When I try to run the program it returns none in the python shell and doesn't complete the function I would like it to. I would like it to write "your prompt has been posted" if there are under ten characters and write "The prompt is too long" if there are over 10 character. Thanks in advance for the help. It is greatly appreciated
label = Label(tk, text="Prompt:")
label.place(relx=0.1, rely=0.2, anchor=CENTER)
text = Text(tk, width=50, height=6, bg="gray")
text.place(relx=0.62, rely=0.2, anchor=CENTER)
def diary():
print("Why does this not work")
def begin():
while True:
answer = input(text.insert(INSERT, diary))
if len(answer) <= 10:
print("Your prompt has been posted")
else:
print("The prompt is too long")
button = Button(tk, text="Submit", command=begin)
button.place(relx=0.5, rely=0.5, anchor=CENTER)
The code never ends because you told it to run a loop forever without changing anything that would cause it to stop.
Also, whatever you think this code is doing, it's probably not doing it. I count at least three things wrong with this one line of code:
answer = input(text.insert(INSERT, diary))
The input command will read in put from the command line (technically, stdin), which is not something you typically do in a GUI. You are passing it the result of a call to text.insert, but text.insert isn't documented to return anything. Plus, you're giving text.insert a function where it expects a string.
If you want to insert what the function diary returns, you must a) define diary to do something, and b) call it as a function. For example:
def diary():
return "something"
...
text.insert(INSERT, diary())
If your real goal is to have begin get what the user has entered in the GUI and check the length, then you need to remove the while loop and replace the call to insert with get:
def begin():
answer = text.get("1.0", "end-1c")
if len(answer) <= 10:
print("Your prompt has been posted")
else:
print("The prompt is too long")