Reputation: 1474
I want my GUI to ask for login again after been left idle for 5 minutes when you login but the root window should stay when tick the checkbutton.
Challenges:
As soon as I run the script, the messagebox parsed under "session_ends" function pops-up.
When I type the the name and password into the entry widget and I tick the checkbutton, another window also pops-up.
import tkinter as tk
import sys
from tkinter import messagebox
name=("user")
password=("python3")
def login_in():
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
entry1.set("") # This clears entry1
entry2.set("") # this clears entry2
def close():
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
sys.exit() #Ends the script
def session_end():
messagebox.showinfo("session expired","kindly login again")
def continue_session():
root.deiconify()
root=tk.Tk()
log = tk.Toplevel() #
root.geometry("350x350")
log.geometry("200x200")
entry1 = tk.Entry(log) #Username entry
entry2 = tk.Entry(log) #Password entry
check = tk.Checkbutton(log,text="keep me
login",command=continue_session)#root should stay when you tick checkbutton
button1 = tk.Button(log, text="Login", command=login_in) #Login button
button2 = tk.Button(log, text="Cancel", command=close) #Cancel button
label1 = tk.Label(root, text="This main ui after being idle for 5 minutes \n
You need to login for the main ui to open")
entry1.pack()
entry2.pack()
check.pack()
button1.pack()
button2.pack()
label1.pack()
root.withdraw()
root.after(5000,session_end())
root.mainloop()
EDIT: with the above code have edited it with the answer @Bryan Oakley provided but is the idle timeout the work after 5 minute being idle
import tkinter as tk
import sys
name=("user")
password=("python3")
after_id=None
def reset_timer(event=None):
global after_id
if after_id is not None:
root.after_cancel(after_id)
after_id = root.after(300000,session_end)
def login_in():
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def close():
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
sys.exit() #Ends the script
def session_end():
messagebox.showinfo("session expired","kindly login again")
def continue_session():
if after_id is not None:
root.deiconify()
def print_some():
print("This is idle timeout")
root=tk.Tk()
log = tk.Toplevel() #
root.geometry("350x350")
log.geometry("200x200")
entry1 = tk.Entry(log) #Username entry
entry2 = tk.Entry(log) #Password entry
check = tk.Checkbutton(log,text="keep me
login",command=continue_session)#root should stay when you tick checkbutton
button1 = tk.Button(log, text="Login", command=login_in) #Login button
button2 = tk.Button(log, text="Cancel", command=close) #Cancel button
label1 = tk.Label(root, text="This main ui after being idle for 5 minutes \n
You need to login for the main ui\to open")
print_button = tk.Button(root,text="print",command=print_some).pack()
entry1.pack()
entry2.pack()
check.pack()
button1.pack()
button2.pack()
label1.pack()
root.withdraw()
root.bind_all("<Any-KeyPress>",reset_timer)
root.bind_all("<Any-ButtonPress>",reset_timer)
root.mainloop()
Upvotes: 0
Views: 3467
Reputation: 1
time_out = 30000
def reset_timer(event=None):
global time_out
if event is not None:
time_out = 30000
else:
pass
def reduce_time_out():
global time_out
time_out = time_out-1000
print(time_out)
root.after(1000,reduce_time_out)
if time_out ==0:
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
messagebox.showinfo("session expired","kindly login again")
sys.exit()
root.after(1000,reduce_time_out)
root.bind_all("<Any-KeyPress>",reset_timer)
root.bind_all("<Any-ButtonPress>",reset_timer)
Upvotes: 0
Reputation: 385950
How to set idle time-out for your GUI in Tkinter (PYTHON 3.6.1)
A simple solution is to create a function that will end a session, and then schedule that function to run in the future. You are attempting this, but you are calling after
incorrectly.
The key to making this be a true idle timeout is to know when the user is "idle". A simple solution is to make a global binding for <Any-KeyPress>
and <Any-ButtonPress>
The first thing is to create a global or instance variable to remember the id of the command we're running with after
:
after_id = None
The next step is to create a function to reset the timer. It needs to accept an event since one is automatically passed by tkinter. However, we want to be able to call the function directly so we'll make it optional.
def reset_timer(event=None):
global after_id
if after_id is not None:
root.after_cancel(after_id)
after_id = root.after(5000, session_end)
To start the session, we can directly call the function:
reset_timer()
Next, we can set up bindings to reset the timer on user activity. In this case I'll define activity as any button or key press. We do it like this:
root.bind_all("<Any-KeyPress>", reset_timer)
root.bind_all("<Any-ButtonPress>", reset_timer)
Upvotes: 2