Enter Key binding in Tkinter - python

So, I've been trying to bind the enter key to press the button I have in this python program -- yes I've seen the numerous other questions related to this, but none of their code worked with this program for whatever reason. Posting code below to see if anyone has a good solution.
The below code does everything as expected -- it will pull up the GUI, show the goofy jar-jar picture, the button, and the entry fields with the prefilled text, but the enter key on my keyboard will not produce a result as it happens when I press the button with the mouse.
import tkinter as tk
from PIL import Image, ImageTk, ImageTransform
from tkinter.filedialog import askopenfile
root = tk.Tk()
class guiMenu:
def __init__(self, master):
myFrame = tk.Frame(master)
# logo
logo = Image.open('jar.jpg')
logo2 = logo.resize((200, 200), Image.ANTIALIAS)
logo2 = ImageTk.PhotoImage(logo2)
self.logo_label = tk.Label(image=logo2)
self.logo_label.image = logo2
self.logo_label.grid(column=1, row=0)
# instructions
self.instructions = tk.Label(master,
text="Input your email address and password to extract email attachments.\n "
"You should also select the folder you wish the attachments to reach.")
self.instructions.grid(columnspan=3, column=0, row=3)
# store the user login info in variables
def storeUserLogin():
clientEmailInput = self.emailEntry.get()
clientPasswordInput = self.passwordEntry.get()
print(clientEmailInput, clientPasswordInput)
# delete email prefill on click
def onEmailClick(event):
self.emailEntry.configure()
self.emailEntry.delete(0, 100) # this deletes the preexisting text for email entry
self.emailEntry.unbind('<Button-1>', self.on_click_id)
# delete pw prefill on click
def onPWClick(event):
self.passwordEntry.configure()
self.passwordEntry.delete(0, 100) # this deletes the preexisting text for email entry
self.passwordEntry.unbind('<Button-1>', self.on_click_id2)
# email entry box
self.emailEntry = tk.Entry(master, width=50)
# emailEntry = tk.StringVar(None)
# emailEntry.set("Email Address")
self.emailEntry = tk.Entry()
self.emailEntry.insert(0, "Email Address")
self.emailEntry.configure()
self.emailEntry.grid(column=1, row=1)
# on-click function
self.on_click_id = self.emailEntry.bind('<Button-1>', onEmailClick)
# enter key function
def enterFunction(event=None):
master.bind('<Return>', lambda event=None, loginButton.invoke())
# password entry box
self.passwordEntry = tk.Entry()
self.passwordEntry.insert(0, "Password")
self.passwordEntry.grid(column=1, row=2)
# on click function
self.on_click_id2 = self.passwordEntry.bind('<Button-1>', onPWClick)
# button to login
def loginButton():
self.loginButtonText = tk.StringVar()
self.loginButton = tk.Button(master, textvariable=self.loginButtonText, font="Arial",
commands=lambda: [storeUserLogin(), enterFunction()],
width=5, height=2,
bg="white", fg="black")
self.loginButtonText.set("LOGIN")
self.loginButton.grid(column=1, row=4)
self.canvas = tk.Canvas(root, width=600, height=250)
self.canvas.grid(columnspan=3)
g = guiMenu(root)
root.mainloop()

You're Binding the loginButton function in another function which is never called and you are writing the OOPs wrong here. You shouldn't define your functions in init function.Here is some changes that i made in your code. I am not good at explaining but i hope this will help. I wrote reasons too in code where i change the code.
import tkinter as tk
from PIL import Image, ImageTk, ImageTransform
from tkinter.filedialog import askopenfile
root = tk.Tk()
class guiMenu:
def __init__(self, master):
#definr master in Class so we can use it from entire class
self.master = master
myFrame = tk.Frame(master)
# logo
logo = Image.open('Spitball\Spc.jpg')
logo2 = logo.resize((200, 200), Image.ANTIALIAS)
logo2 = ImageTk.PhotoImage(logo2)
self.logo_label = tk.Label(image=logo2)
self.logo_label.image = logo2
self.logo_label.grid(column=1, row=0)
#Create Email Entry box (we are creating Email and Password entry box when class is initialize)
self.emailEntry = tk.Entry(master, width=50)
self.emailEntry.insert(0, "Email Address")
# emailEntry = tk.StringVar(None)
# emailEntry.set("Email Address")
# self.emailEntry = tk.Entry() # You should not create two entry boxes with same name
# self.emailEntry.configure() # We dont need to configure email entry here
#Create Password Entry box (we are creating Email and Password entry box when class is initialize)
self.passwordEntry = tk.Entry()
self.passwordEntry.insert(0, "Password")
#Grid the email and password entry box.Here email entry box will display first beacuse we grid it first.
self.emailEntry.grid(column=1, row=1)
self.passwordEntry.grid(column=1, row=2)
# instructions
self.instructions = tk.Label(master,
text="Input your email address and password to extract email attachments.\n "
"You should also select the folder you wish the attachments to reach.")
self.instructions.grid(columnspan=3, column=0, row=3)
#Create Login Button
self.loginButtonText = tk.StringVar()
self.loginButton = tk.Button(self.master, textvariable=self.loginButtonText, font="Arial",
command=self.storeUserLogin,
width=5, height=2,
bg="white", fg="black")
# I dont see here the use of Canvas so i commented out it.
# self.canvas = tk.Canvas(self.master, width=600, height=250)
# on-click function
self.on_click_id = self.emailEntry.bind('', self.onEmailClick)
# on click function
self.on_click_id2 = self.passwordEntry.bind('', self.onPWClick)
#Bind enter key with loginButtonFunc
self.master.bind('',self.loginButtonFunc)
def storeUserLogin(self):
# store the user login info in variables
clientEmailInput = self.emailEntry.get()
clientPasswordInput = self.passwordEntry.get()
print(clientEmailInput, clientPasswordInput)
# delete email prefill on click
def onEmailClick(self,event):
self.emailEntry.configure()
self.emailEntry.delete(0, 100) # this deletes the preexisting text for email entry
self.emailEntry.unbind('', self.on_click_id)
# delete pw prefill on click
def onPWClick(self,event):
self.passwordEntry.configure()
self.passwordEntry.delete(0, 100) # this deletes the preexisting text for email entry
self.passwordEntry.unbind('', self.on_click_id2)
# button to login
def loginButtonFunc(self,event=None):
self.loginButtonText.set("LOGIN")
self.loginButton.grid(column=1, row=4,pady=5)
# self.canvas.grid(columnspan=3)
g = guiMenu(root)
root.mainloop()

Related

How to make Tkinter Entry field visible on button press

I am making a simple Log In Menu using Python Tkinter. The code works for logging in and all that stuff but I want to make a working create new account button or something like that. I will be doing that using lists but first I need to make sure that the Entry field pops up on clicking the create new account button, Here is the code :-
from tkinter import*
from tkinter import messagebox
class Login:
def __init__(self,root):
self.root=root
self.root.title("Login")
self.root.geometry("1199x600+100+50")
self.bg=PhotoImage(file="png.png")
self.bg_image=Label(self.root,image=self.bg).place(x=0,y=0,relwidth=1,relheight=1)
#Frame
Frame_login=Frame(self.root,bg="white")
Frame_login.place(x=150,y=150,height=340,width=500)
title=Label(Frame_login,text="Login Here",font=("Impact",35, "bold","underline"),fg="red",bg="white").place(x=160,y=30)
desc=Label(Frame_login,text="Login Area",font=("Goudy old",15, "bold","underline"),fg="purple",bg="white").place(x=80,y=100)
lbl_user=Label(Frame_login,text="Username:",font=("Goudy old",15,"underline","bold"),fg="#00ffff",bg="white").place(x=115,y=140)
self.txt_user=Entry(Frame_login,font=("times new roman", 15),bg="lightgray")
self.txt_user.place(x=115,y=170,width=350,height=35)
lbl_pass=Label(Frame_login,text="Password:",font=("Goudy old",15,"underline","bold"),fg="#00ffff",bg="white").place(x=115,y=210)
self.txt_pass=Entry(Frame_login,font=("times new roman", 15),bg="lightgray")
self.txt_pass.place(x=115,y=240,width=350,height=35)
forget_btn= Button(Frame_login,command=self.register,text="Create New Account",cursor="hand2", bg="white", fg='lime', bd=0,font=("times new roman", 12)).place(x=115,y=280)
log_btn= Button(self.root,command=self.login_function,text="Login",cursor="hand2", fg="#d77337", bg="#d77337", font=("times new roman", 20)).place(x=315,y=470,width=180,height=40)
def login_function(self):
if self.txt_pass.get()=="" or self.txt_user.get()=="":
messagebox.showerror("Error!","All fields are required", parent=self.root)
elif self.txt_user.get()!="abcd" or self.txt_pass.get()!="1234":
messagebox.showerror("Error!"," Invalid Username or Password", parent=self.root)
else:
messagebox.showinfo("Welcome!","Succesfully Logged In!")
root=Tk()
obj=Login(root)
root.mainloop()
Here is a simple example of how that might look like:
from tkinter import Tk, Frame, Button, Entry, Label
class Login(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
# data frame
self.data_frame = Frame(self)
self.data_frame.pack(pady=10)
# username:
Label(self.data_frame, text='Username:').pack()
# username entry
self.username = Entry(self.data_frame)
self.username.pack()
# password:
Label(self.data_frame, text='Password:').pack()
# password entry
self.password = Entry(self.data_frame)
self.password.pack()
# button frame
self.btn_frame = Frame(self)
self.btn_frame.pack()
# login btn
Button(self.btn_frame, text='Login', command=self.login).pack(side='left', padx=10, pady=10)
# signup button
Button(self.btn_frame, text='Sign Up', command=self.sign_up).pack(side='left', padx=10, pady=10)
def login(self):
print('login successful')
root.destroy()
def sign_up(self):
SignUp(root).pack()
self.destroy()
class SignUp(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
# data frame
self.data_frame = Frame(self)
self.data_frame.pack(pady=10)
# username:
Label(self.data_frame, text='Username:').pack()
# username entry
self.username = Entry(self.data_frame)
self.username.pack()
# password:
Label(self.data_frame, text='Password:').pack()
# password entry
self.password = Entry(self.data_frame)
self.password.pack()
# button frame
self.btn_frame = Frame(self)
self.btn_frame.pack()
# login btn
Button(self.btn_frame, text='Sign Up', command=self.sign_up).pack(side='left', padx=10, pady=10)
# signup button
Button(self.btn_frame, text='Cancel', command=self.cancel).pack(side='left', padx=10, pady=10)
def sign_up(self):
print('Signed up')
Login(root).pack()
self.destroy()
def cancel(self):
Login(root).pack()
self.destroy()
root = Tk()
Login(root).pack()
root.mainloop()
Both classes are pretty much frames and can be changed depending on which button user presses, can also add more functionality to the methods. Otherwise both classes are pretty much identical, they are almost copies just a few things like button names and method names are changed the rest is the same

Tkinter: How to pass arguments from entry to function (and glitch in exiting)

I have been working on a login page in Tkinter for fun, but I am unable to make a function that checks the entries and compares them to a specific input. Also, the code adds a messagebox and calls a function every time I exit the window.
My code is:
from tkinter import *
from tkinter import messagebox
root = Tk()
root.title("Login")
def makeUname(d):
if messagebox.askyesno("Submit?", "Is this correct?"):
global password
username = uname.get()
uname.grid_forget()
return password
def makePasswd(d):
if messagebox.askyesno("Submit?", "Is this correct?"):
global username
password = uname.get()
passwd.grid_forget()
return username
def button():
makeUname("")
makePasswd("")
quitbutt.grid_forget()
uname = Entry(root)
uname.grid(row=1, column=1)
passwd = Entry(root, show="*")
passwd.grid(row=2, column=1)
quitbutt = Button(root, text="Login", command=button)
quitbutt.grid(row=3, column=1, columnspan=2, sticky='nesw')
root.mainloop()
makeUname("")
makePasswd("")
if(username == "username" and password == "password"):
messagebox.showwarning("Warning", "Sorry, this isn't programmed yet.")
else:
messagebox.showwarning("Nope", "Nope. Nice try.")
Can someone help me with my code? Should I use a different setup or method?
There was many problem so I changed all to make it simpler.
I added comments in code to explain some elements.
from tkinter import *
from tkinter import messagebox
# --- functions ---
def button():
# use global variable (instead of local variables)
# to keep username, password outside function and keep after closing window
global username
global password
username = uname.get()
password = passwd.get()
#print('button:', username, password)
if username == "username" and password == "password":
messagebox.showwarning("Warning", "Sorry, this isn't programmed yet.")
root.destroy() # close window
else:
messagebox.showwarning("Nope", "Nope. Nice try.")
# window still open
# --- main ---
# default values at start
# Someone can exit window without using Button
# and it would not create this variables in button()
username = ""
password = ""
root = Tk()
root.title("Login")
uname = Entry(root)
uname.grid(row=1, column=1)
passwd = Entry(root, show="*")
passwd.grid(row=2, column=1)
quitbutt = Button(root, text="Login", command=button)
quitbutt.grid(row=3, column=1, columnspan=2, sticky='nesw')
# start program (start engine, display window, (re)draw widgets, handle events, get events from system (keyboard, mouse), send events to widgets)
root.mainloop()
# after closing window this variables still have values from window
print("after mainloop:", username, password)

How to remove the widgets and replace them in python

i'm new to tkinter and wanted to change an already existing piece of code I made into GUI. The piece of code below is a username and password system. The thing I need help with is that I can not figure out how to get a new box or to remove the widgets of the gui. Nothing is wrong with the code below but I wanted to show you as it shows you how I've coded it and how to make a new box based on this code.
Btw I am in python 3.5.1 and on windows 10.
import tkinter
from tkinter import *
import tkinter.messagebox as box
import time
def dialog1():
username=entry1.get()
password = entry2.get()
if (username == 'Noel' and password == 'Music quiz'):
box.showinfo('info','You may now enter the Music quiz')
else:
box.showinfo('info','Invalid Login')
window = Tk()
window.title('Music quiz')
window.geometry("300x125")
window.wm_iconbitmap('Favicon.ico')
frame = Frame(window)
Label1 = Label(window,text = 'Username:')
Label1.pack()
entry1 = Entry()
entry1.pack()
Label2 = Label(window,text = 'Password: ')
Label2.pack()
entry2 = Entry()
entry2.pack()
Here is edited code that I think will do what you have asked. Explanations are in the code in the form of comments.
import tkinter
from tkinter import *
import tkinter.messagebox as box
import time
def dialog1():
username=entry1.get()
password = entry2.get()
if (username == 'Noel' and password == 'Music quiz'):
box.showinfo('info','You may now enter the Music quiz')
loginframe.destroy() #remove the login frame
##code to create the quiz goes here##
else:
box.showinfo('info','Invalid Login')
window = Tk()
window.title('Music quiz')
window.geometry("300x125")
window.wm_iconbitmap('Favicon.ico')
loginframe = Frame(window) #create an empty frame for login
loginframe.pack() #put the empty frame into the window
#all elements below are put into the 'loginframe' Frame
Label1 = Label(loginframe,text = 'Username:')
Label1.pack()
entry1 = Entry(loginframe)
entry1.pack()
Label2 = Label(loginframe,text = 'Password: ')
Label2.pack()
entry2 = Entry(loginframe)
entry2.pack()
donebttn = Button(loginframe, text='Done',
command=dialog1) #create a button to continue
donebttn.pack() #display that button
mainloop()

Tkinter widget unable to be removed (created by a for loop)

I have created a variety of Tkinter widgets with for loops. All of them remove fine, except for the "lock_btn" widget. When I press that button the lock button stays on the page (although the rest of the code in the function works). I have tried both with and without globals (the code you see includes globals).
import tkinter
import tkinter.messagebox
#Setting properties for the window
window = tkinter.Tk()
window.title("Shutdown Timer")
window.geometry("250x300")
window.configure(background="black")
def Login():
for x in range(0,5):
login_window[x].pack_forget()
def Auth():
if usr.get() == "isensedemons":
if pas.get() == password:
Login()
else:
tkinter.messagebox.showinfo("Login Error", "Incorrect Username or Password")
else:
tkinter.messagebox.showinfo("Login Error", "Incorrect Username or Password")
def Lock():
global lock_btn
for x in range(0,1):
lock_btn.pack_forget()
for x in range(0,5):
login_window[x].pack()
lock_btn = tkinter.Button(window, text="Lock", fg="white", bg="black", command=Lock)
lbl_usr = tkinter.Label(window, text="Username", fg="white", bg="black")
usr = tkinter.Entry(window)
lbl_pas = tkinter.Label(window, text="Password", fg="white", bg="black")
pas = tkinter.Entry(window, show="•")
btn = tkinter.Button(window, text="Authenticate", fg="white", bg="black", command=Auth)
password = "password"
login_window = [lbl_usr,usr,lbl_pas,pas,btn]
class Create():
lock_btn.pack()
lock_btn.place(rely=1, relx=1, anchor="se")
Create()
#Starts the Program
window.mainloop()
You start by calling lock_btn.pack(0), then you switch to using place(...). So, the widget is being managed by place because it can be only managed by one geometry manager. When you call pack_forget it has no effect because pack isn't in control of the widget.

Tkinter. Press Enter in Entry box. Append to Text box. How?

I am making a chat program and decided to use Tkinter for the interface.
What I wanna do is a breeze in C# but Tkinter is new to me.
Basically I have a form with a Entry control and a Text control.
I want to know how to append text from the Entry control to the Text control after the user presses Enter.
Here's my code so far:
from tkinter import *
class Application:
def hello(self):
msg = tkinter.messagebox.askquestion('title','question')
def __init__(self, form):
form.resizable(0,0)
form.minsize(200, 200)
form.title('Top Level')
# Global Padding pady and padx
pad_x = 5
pad_y = 5
# create a toplevel menu
menubar = Menu(form)
#command= parameter missing.
menubar.add_command(label="Menu1")
#command= parameter missing.
menubar.add_command(label="Menu2")
#command= parameter missing.
menubar.add_command(label="Menu3")
# display the menu
form.config(menu=menubar)
# Create controls
label1 = Label(form, text="Label1")
textbox1 = Entry(form)
#command= parameter missing.
button1 = Button(form, text='Button1')
scrollbar1 = Scrollbar(form)
textarea1 = Text(form, width=20, height=10)
textarea1.config(yscrollcommand=scrollbar1.set)
scrollbar1.config(command=textarea1.yview)
textarea1.grid(row=0, column=1, padx=pad_x, pady=pad_y, sticky=W)
scrollbar1.grid(row=0, column=2, padx=pad_x, pady=pad_y, sticky=W)
textbox1.grid(row=1, column=1, padx=pad_x, pady=pad_y, sticky=W)
button1.grid(row=1, column=2, padx=pad_x, pady=pad_y, sticky=W)
form.mainloop()
root = Tk()
Application(root)
So you're using a tkinter.Text box, which supports the .insert method. Let's use it!
def __init__(self,form):
# Lots of your code is duplicated here, so I'm just highlighting the main parts
button1 = Button(form, text='Button1', command = self.addchat)
self.textbox = textbox1 # to make it accessible outside your __init__
self.textarea = textarea1 # see above
form.bind("<Return>", lambda x: self.addchat())
# this is the magic that makes your enter key do something
def addchat(self):
txt = self.textbox.get()
# gets everything in your textbox
self.textarea.insert(END,"\n"+txt)
# tosses txt into textarea on a new line after the end
self.textbox.delete(0,END) # deletes your textbox text

Categories