How to get user input from tkinter with python
Clash Royale CLAN TAG#URR8PPP
How to get user input from tkinter with python
It's kind of an email sending app, the user writes in his email address, password and the email address of the other person where he wants to send his mail to. And the subject and the message. This is the idea.
I made a little window with tkinter and I want that if the user writes down his thinks and click the send email button its send the email. But it gives errors:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:tkinter__init__.py", line 1702, in __call__return self.func(*args)
line 37, in email_send server.login(from_address, password.get())
File "C:smtplib.py", line 721, in login initial_response_ok=initial_response_ok)
File "C:smtplib.py", line 631, in auth (code, resp) = self.docmd("AUTH", mechanism + " " + response)
TypeError: must be str, not bytes
I think there is something with the way I'm getting the input
from tkinter import *
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
window = Tk()
window.title("E-mail sender")
window.geometry("300x350")
fromaddrs = StringVar()
password = StringVar()
toaddrs = StringVar()
subject = StringVar()
messagen = StringVar()
from_address = fromaddrs.get()
to_address = toaddrs.get()
msg = MIMEMultipart()
msg['From'] = from_address
msg['To'] = to_address
msg['Subject'] = subject.get()
message = messagen.get()
msg.attach(MIMEText(messagen.get(), 'plain'))
entry_from_address = Entry(window, textvariable=fromaddrs)
entry_from_password = Entry(window, textvariable=password)
entry_to_address = Entry(window, textvariable=toaddrs)
entry_subject = Entry(window, textvariable=subject)
entry_message = Entry(window, textvariable=messagen)
def email_send(event):
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(from_address, password.get())
text = msg.as_string()
server.sendmail(from_address, to_address, text)
server.quit()
print("Email send!")
label_from_address = Label(window, text="Email address: ")
label_from_password = Label(window, text="Password:")
label_to_address = Label(window, text="Message to:")
label_subject = Label(window, text="Subject:")
label_message = Label(window, text="Message:")
entry_from_address.grid(row=0, column=1)
entry_from_password .grid(row=1, column=1)
entry_to_address.grid(row=2, column=1)
entry_subject.grid(row=3, column=1)
entry_message.grid(row=4, column=1)
label_from_address.grid(row=0, sticky=E)
label_from_password .grid(row=1, sticky=E)
label_to_address.grid(row=2, sticky=E)
label_subject.grid(row=3, sticky=E)
label_message.grid(row=4, sticky=E)
email_send_button = Button(window, text="Send email")
email_send_button.bind("<Button-1>", email_send)
email_send_button.grid(columnspan=2)
window.mainloop()
I hope someone can help
I made some changes in the code, now the e-mails and the password working, but the subject and the text isn't:
fromaddrs = tkinter.StringVar()
password = tkinter.StringVar()
toaddrs = tkinter.StringVar()
subject = tkinter.StringVar()
message = tkinter.StringVar()
entry_from_address = ttk.Entry(window, textvariable=fromaddrs)
entry_from_password = ttk.Entry(window, textvariable=password)
entry_to_address = ttk.Entry(window, textvariable=toaddrs)
entry_subject = ttk.Entry(window, textvariable=subject)
entry_message = ttk.Entry(window, textvariable=message)
msg = MIMEMultipart()
msg['From'] = fromaddrs.get()
msg['To'] = toaddrs.get()
msg['Subject'] = subject.get()
msg.attach(MIMEText(message.get(), 'plain'))
def email_send(*args):
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddrs.get(), password.get())
server.sendmail(fromaddrs.get(), toaddrs.get(), msg.as_string())
server.quit()
print("The message send!")
send_button = tkinter.Button(window, text="Send e-mail", command=email_send)
send_button.grid(columnspan=2)
from_address = fromaddrs.get()
1 Answer
1
To be honest I don't know if there is a direct solution to your problem. This is simply one of the pitfalls of tkinter. I have spent some time trying to develop my own custom tkinter widgets that rely on the basic bind
function. This way, instead of using the preinstalled entry widget, I simply bind a keyboard event to a particular label, and as I type the text of this label changes. Once I want to collect/store the text that I entered, I would simply use the cget('text')
for my label. Sadly, I have not really gotten to making the code library for such an entry widget. I have however previously written some raw code for such entry widgets so I know they will work.
bind
cget('text')
I add cget to my label, but it's sending me what is in the label,not what the use write in the entry. Or I not quite sure how can I do it in another way
– Forzor
Aug 12 at 20:05
You can look into bindings and events for widget in tkinter here. What you can do is bind the <Button-1> event to a label. This will call a function wherein you focusin the label and bind the <Keyboard> event to the label. This will call another function which will add the letters you type to a string as you type, and simultaneously reconfigure the text within the label to reflect the text within the string. When you are done you simply have a button elsewhere to unbind these events from the label.
– ZackBoi
Aug 12 at 23:35
This might seem complicated, and that is because it is. However, I haven't been doing Python for that long and I am still in highschool so I trust you can figure it out if you cannot find another solution and are willing to put in the work. I am trying to make the library I mentioned before and once I make it for an entry field (which is the widget up next) I will be happy to share!
– ZackBoi
Aug 12 at 23:37
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Part of the problem is that you're doing
from_address = fromaddrs.get()
about a millisecond after the variable has been created, way before the user has a chance to input anything.– Bryan Oakley
Aug 12 at 15:30