I'm writing a program with Python's tkinter library.
My major problem is that I don't know how to create a timer or a clock like hh:mm:ss.
I need it to update itself (that's what I don't know how to do); when I use time.sleep() in a loop the whole GUI freezes.
Tkinter root windows have a method called after which can be used to schedule a function to be called after a given period of time. If that function itself calls after you've set up an automatically recurring event.
Here is a working example:
# for python 3.x use 'tkinter' rather than 'Tkinter'
import Tkinter as tk
import time
class App():
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(text="")
self.label.pack()
self.update_clock()
self.root.mainloop()
def update_clock(self):
now = time.strftime("%H:%M:%S")
self.label.configure(text=now)
self.root.after(1000, self.update_clock)
app=App()
Bear in mind that after doesn't guarantee the function will run exactly on time. It only schedules the job to be run after a given amount of time. It the app is busy there may be a delay before it is called since Tkinter is single-threaded. The delay is typically measured in microseconds.
Python3 clock example using the frame.after() rather than the top level application. Also shows updating the label with a StringVar()
#!/usr/bin/env python3
# Display UTC.
# started with https://docs.python.org/3.4/library/tkinter.html#module-tkinter
import tkinter as tk
import time
def current_iso8601():
"""Get current date and time in ISO8601"""
# https://en.wikipedia.org/wiki/ISO_8601
# https://xkcd.com/1179/
return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.now = tk.StringVar()
self.time = tk.Label(self, font=('Helvetica', 24))
self.time.pack(side="top")
self.time["textvariable"] = self.now
self.QUIT = tk.Button(self, text="QUIT", fg="red",
command=root.destroy)
self.QUIT.pack(side="bottom")
# initial time display
self.onUpdate()
def onUpdate(self):
# update displayed time
self.now.set(current_iso8601())
# schedule timer to call myself after 1 second
self.after(1000, self.onUpdate)
root = tk.Tk()
app = Application(master=root)
root.mainloop()
from tkinter import *
import time
tk=Tk()
def clock():
t=time.strftime('%I:%M:%S',time.localtime())
if t!='':
label1.config(text=t,font='times 25')
tk.after(100,clock)
label1=Label(tk,justify='center')
label1.pack()
clock()
tk.mainloop()
You should call .after_idle(callback) before the mainloop and .after(ms, callback) at the end of the callback function.
Example:
import tkinter as tk
import time
def refresh_clock():
clock_label.config(
text=time.strftime("%H:%M:%S", time.localtime())
)
root.after(1000, refresh_clock) # <--
root = tk.Tk()
clock_label = tk.Label(root, font="Times 25", justify="center")
clock_label.pack()
root.after_idle(refresh_clock) # <--
root.mainloop()
I have a simple answer to this problem. I created a thread to update the time. In the thread i run a while loop which gets the time and update it. Check the below code and do not forget to mark it as right answer.
from tkinter import *
from tkinter import *
import _thread
import time
def update():
while True:
t=time.strftime('%I:%M:%S',time.localtime())
time_label['text'] = t
win = Tk()
win.geometry('200x200')
time_label = Label(win, text='0:0:0', font=('',15))
time_label.pack()
_thread.start_new_thread(update,())
win.mainloop()
I just created a simple timer using the MVP pattern (however it may be
overkill for that simple project). It has quit, start/pause and a stop button. Time is displayed in HH:MM:SS format. Time counting is implemented using a thread that is running several times a second and the difference between the time the timer has started and the current time.
Source code on github
from tkinter import *
from tkinter import messagebox
root = Tk()
root.geometry("400x400")
root.resizable(0, 0)
root.title("Timer")
seconds = 21
def timer():
global seconds
if seconds > 0:
seconds = seconds - 1
mins = seconds // 60
m = str(mins)
if mins < 10:
m = '0' + str(mins)
se = seconds - (mins * 60)
s = str(se)
if se < 10:
s = '0' + str(se)
time.set(m + ':' + s)
timer_display.config(textvariable=time)
# call this function again in 1,000 milliseconds
root.after(1000, timer)
elif seconds == 0:
messagebox.showinfo('Message', 'Time is completed')
root.quit()
frames = Frame(root, width=500, height=500)
frames.pack()
time = StringVar()
timer_display = Label(root, font=('Trebuchet MS', 30, 'bold'))
timer_display.place(x=145, y=100)
timer() # start the timer
root.mainloop()
You can emulate time.sleep with tksleep and call the function after a given amount of time. This may adds readability to your code, but has its limitations:
def tick():
while True:
clock.configure(text=time.strftime("%H:%M:%S"))
tksleep(0.25) #sleep for 0.25 seconds
root = tk.Tk()
clock = tk.Label(root,text='5')
clock.pack(fill=tk.BOTH,expand=True)
tick()
root.mainloop()
Related
I have just started using kivy and Tkinter to develop simple apps for starters. Recently, I created a digital Clock program that can be used on desktop. It works fine because it is simple with just a few lines of codes. I wanted to add one functionality which is Alarm. Can anyone please guide me on how to go about it.
It is my first time, so am not sure if I posted this question the right way or not. So below is the code I used to get my output.
import tkinter as tk
from tkinter.ttk import *
# I imported strftime to use for formatting time details of the program.
from time import strftime
import datetime
# creating tkinter window
root = tk.Tk()
root.title('Clock')
root.attributes('-topmost', True) # This line here sets our app to be the
topmost in the window screen.
# root.attributes('-topmost', False) When this line is added, the app will
no longer have that topmost privilege.
# This function will show us the calender on the program.
def datetime():
string1 = strftime('%d/%b/%Y') # This line can be joined with the other one below with \n and it will work.
lbl1.config(text=string1)
lbl1.after(1000, datetime)
lbl1 = Label(root, font=('verdana', 20, 'bold'), background='black',
foreground='#808000')
lbl1.pack(fill=tk.BOTH)
datetime()
# This function is used to display time on our label
def time():
string = strftime('%H:%M:%S %p')
lbl.config(text=string)
lbl.after(1000, time) # updating the label.
# Giving the Label some style.
lbl = Label(root, font=('verdana', 22, 'bold'), background='#050929',
foreground='silver')
# packing the Label to the center.
# of the tkinter window
lbl.pack(anchor=tk.CENTER)
time()
root.mainloop()
For a procedural solution just add the after method of tkinter.
import tkinter as tk
import datetime
def tick():
showed_time = ''
current_time = datetime.datetime.now().strftime("%H:%M:%S")
if showed_time != current_time:
showed_time = current_time
clock.configure(text=current_time)
clock.after(1000, tick)
if showed_time == '10:00:00': #10 o'clock print alarm
print('alarm')
root=tk.Tk()
clock = tk.Label(root)
clock.pack()
tick()
root.mainloop()
An object orientated solution could be this:
import tkinter as tk
from tkinter import ttk as ttk
import datetime
root=tk.Tk()
class AlarmClock(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.all_alarms = []
self.ini_body()
self.ini_clock()
self.ini_mid()
self.ini_table()
def ini_body(self):
self.up_frame = tk.Frame(self)
self.mid_frame= tk.Frame(self)
self.dow_frame= tk.Frame(self)
self.up_frame.pack(side='top')
self.mid_frame.pack(side='top',fill='x')
self.dow_frame.pack(side='top')
def ini_clock(self):
self.clock = tk.Label(self.up_frame, text='00:00:00')
self.clock.pack(side='top', fill='x')
self.tick()
def tick(self):
self.showed_time = ''
self.current_time = datetime.datetime.now().strftime("%H:%M:%S")
if self.showed_time != self.current_time:
self.showed_time = self.current_time
self.clock.configure(text=self.current_time)
if self.showed_time in self.all_alarms:
self.invoke_alarm(self.showed_time)
self.after(1000, self.tick)
def ini_table(self):
self.table = ttk.Treeview(self.dow_frame,height=10,columns=('#1'))
self.table.heading('#0', text='Alarm ID')
self.table.heading('#1', text='Alarm time')
self.table.pack()
def ini_mid(self):
self.alarm_id = tk.Entry(self.mid_frame,justify='center')
self.alarm_id.insert('end','Alarm ID')
self.alarm_time = tk.Entry(self.mid_frame,justify='center')
self.alarm_time.insert('end','HH:MM')
self.set_button = tk.Button(self.mid_frame, text='set alarm',
command=self.set_alarm)
self.cancel_button=tk.Button(self.mid_frame, text='cancel alarm',
command=self.cancel_alarm)
self.alarm_time.grid(column=1,row=0,sticky='ew')
self.alarm_id.grid(column=0,row=0, sticky='we')
self.set_button.grid(column=0, row=1, sticky='ew')
self.cancel_button.grid(column=1, row=1, sticky='ew')
self.mid_frame.columnconfigure(0, weight=1)
self.mid_frame.columnconfigure(1, weight=1)
def set_alarm(self):
Id = self.alarm_id.get()
time = self.alarm_time.get()
self.table.insert('','end', iid=Id, text=Id,
values=time, tags=time)
self.register_alarm()
def cancel_alarm(self):
Id = self.alarm_id.get()
time = self.alarm_time.get()
if self.table.exists(Id):
tag = self.table.item(Id, "tags")[0]
alarm_time=tag+":00"
self.all_alarms.remove(alarm_time)
self.table.delete(Id)
elif self.table.tag_has(time):
Id = self.table.tag_has(time)[0]
tag = self.table.item(Id, "tags")[0]
alarm_time=tag+":00"
self.all_alarms.remove(alarm_time)
self.table.delete(Id)
def register_alarm(self):
self.all_alarms.append(f'{self.alarm_time.get()}:00')
def invoke_alarm(self, time):
self.alarm_window = tk.Toplevel()
self.alarm_window.title('Alarm!')
self.message = tk.Label(self.alarm_window,
text=f"ALARM!! It's {time[:5]} o'clock!")
self.message.pack(fill='both')
alarm = AlarmClock(root)
alarm.pack()
root.mainloop()
Hope you enjoy and let me know if you have any question about it.
Hello I am trying to make a simple script which on key press x starts a timer of 45 sec after that when it reaches 10 sec color text changes to red and when countdown comes 0 I want to destroy the timer gui but not the program, and when i press x again program starts doing stuff again and repeats the process
So far I managed this I tried all day I also tried adding on keypress but it become so complicated and didn't worked so I am asking help here
from tkinter import *
root = Tk()
root.geometry("112x55")
root.overrideredirect(True)
root.lift()
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
root.resizable(0, 0)
seconds = 45
def timer():
global seconds
if seconds > 0:
seconds = seconds - 1
mins = seconds // 60
m = str(mins)
if mins < 10:
m = '0' + str(mins)
se = seconds - (mins * 60)
s = str(se)
if se < 10:
s = '0' + str(se)
time.set(m + ':' + s)
timer_display.config(textvariable=time)
# call this function again in 1,000 milliseconds
root.after(1000, timer)
elif seconds == 0:
seconds.delete("1.0","end")
frames = Frame(root, width=500, height=500)
frames.pack()
time = StringVar()
timer_display = Label(root, font=('Trebuchet MS', 30, 'bold'))
timer_display.place(x=0, y=0)
timer() # start the timer
root.mainloop()
As you used wm_attributes('-transparentcolor', 'white') (but you never set the background color of root and the timer_display to white, so it don't have effect) and overrideredirect(True), that means you want the window totally transparent and borderless. However this has side effect that you may never get the window focus back after the window loses focus.
Also you used wm_attributes('-disabled', True), then you can't have any key press event triggered. It should not be used.
Suggest to use wm_attributes('-alpha', 0.01) to simulate the transparent effect without the above issues.
Below is an example:
from tkinter import *
root = Tk()
root.geometry("+0+0")
root.overrideredirect(True)
root.wm_attributes("-topmost", True)
root.wm_attributes("-alpha", 0.01)
root.resizable(0, 0)
seconds = 45
def countdown(seconds):
if seconds > 0:
mins, secs = divmod(seconds, 60)
timer_display.config(text="{:02d}:{:02d}".format(mins, secs),
fg='red' if seconds <= 10 else 'white')
root.after(1000, countdown, seconds-1)
else:
root.wm_attributes('-alpha', 0.01) # make the window "disappear"
def start_countdown(event):
root.wm_attributes('-alpha', 0.7) # make the window "appear"
countdown(seconds)
timer_display = Label(root, font=('Trebuchet MS', 30, 'bold'), bg='black')
timer_display.pack()
root.bind('x', start_countdown)
root.bind('q', lambda e: root.destroy()) # provide a way to close the window
root.mainloop()
NOTE #1: If the window loses focus, you can still click somewhere near the top-left corner of the screen to resume window focus, although you cannot see the window.
NOTE #2: If you want system-wise key handler, tkinter does not support it. You need to use other module, like pynput.
If you want to destroy the timer GUI, You'll need to make a class like this:
class Timer(Frame):
def __init__(self, master):
super().__init__(master)
# Paste the code you want to run here, make sure you put "self." before it.
# For example:
def clicked():
print('Clicked!')
self.myButton = Button(self, text="Click me!", border=0, width=25, height=1, command=self.clicked)
self.logbtn.grid(columnspan=2)
self.pack()
if seconds == 0:
self.destroy() # by using self.destroy(), you tell it to delete the class.
else:
# You can put whatever you want it to do if it's not 0 here.
tm = Timer(root)
You can bind functions to keystroke events with root.bind(event, callback).
If you are using Linux or Mac, root.overrideredirect(True) will
prevent your application from receiving keystroke events. You can read
more here: Tkinter's overrideredirect prevents certain events in Mac and Linux
Example:
def keydown(e):
print(f"Key pressed: ")
print("Key code:", e.keycode)
print("Key symbol:", e.keysym)
print("Char:", e.char)
def keyup(e):
print(f"Key '{e}' released")
root.bind("<KeyPress>", keydown)
root.bind("<KeyRelease>", keyup)
root.focus_set()
Alternatively, you can also bind to specific keys with <Key-KEYSYM>, e.g. <Key-space> for the spacebar. A list with all keysyms can be found here
Some more events are listed here
Implementation example
Here is an example with a custom CountdownLabel class that is derived from tkinter.Label and automatically binds to the spacebar key event.
app.py
from countdown import CountdownLabel
from tkinter import Frame, StringVar, Tk, Button
root = Tk()
root.geometry("120x60")
root.lift()
root.wm_attributes("-topmost", True)
root.resizable(0, 0)
# Not supported on Linux and MacOS
# root.overrideredirect(True)
# root.wm_attributes("-disabled", True)
# root.wm_attributes("-transparentcolor", "white")
timer_display = CountdownLabel(root, 10, 5)
timer_display.pack(fill="both", expand=True)
timer_display.configure(background="white")
timer_display.configure(font=('Trebuchet MS', 26, 'bold'))
timer_display.focus_set()
root.mainloop()
countdown.py
from tkinter import Label
class CountdownLabel(Label):
# context : A reference to the Label in order to change the text and
# to close it later on
# duration: Total time in seconds
# critical: Length of the last timespan before the countdown finishes
# in seconds
def __init__(self, context, duration, critical):
super().__init__(context)
self.duration = duration
self.critical = critical if duration >= critical else duration
self.update_ui()
self.bound_sequence = "<Key-space>"
self.bound_funcid = self.bind(self.bound_sequence, self.get_handler())
# Returns a function for the event binding that still has access to
# the instance variables
def get_handler(self):
# Gets executed once when the counter starts through handler() and calls
# itself every second from then on to update the GUI
def tick():
self.after(1000, tick)
self.update_ui()
self.duration -= 1
# Gets executed when time left is less than <critical> (default = 10s)
# Sets the font color to red
def change_font_color():
self.configure(foreground="red")
# Destroys itself after the countdown finishes
self.after((self.critical + 1) * 1000, lambda : self.destroy())
def handler(event):
self.unbind(self.bound_sequence, self.bound_funcid)
self.bound_funcid = -1
self.bound_sequence = None
self.after((self.duration - self.critical) * 1000, change_font_color)
tick()
return handler
# Updates the displayed time in the label
def update_ui(self):
mm = self.duration // 60
ss = self.duration % 60
self.config(text="%02d:%02d" % (mm, ss))
def change_binding(self, sequence):
if self.bound_funcid > 0:
self.unbind(self.bound_sequence, self.bound_funcid)
self.bound_sequence = sequence
self.funcid = self.bind(self.bound_sequence, self.get_handler())
I'm writing a program in tkinter using Progressbar. But there is a problem when I added stop function it doesn't work. When I press "stop" button nothing happens, it should stop loading progressbar. I use Python version 3.8. The code below:
from tkinter import *
from tkinter import ttk
import time
root = Tk()
def run():
pb['maximum']=100
for i in range(101):
time.sleep(0.05)
pb['value']=i
pb.update()
def stop():
pb.stop()
runbutt = Button(root,text="Runprogr",command=run)
runbutt.pack()
stopbutt = Button(root,text="Stopbut",command=stop)
stopbutt.pack()
pb = ttk.Progressbar(root,length=300,orient="horizontal")
pb.pack()
root.geometry("300x300")
root.mainloop()
The cause is that pb.stop couldn't stop the function in run.it will also increase by itself.
You could use .after(ms, callback) to add the value(then you no longer need to use time.sleep()).
If you want to stop it,use .after_cancel():
from tkinter import *
from tkinter import ttk
import time
root = Tk()
root.add_value = None
def run():
def add():
if pb['value'] >= 100:
return
pb['value'] += 1
root.add_value = root.after(50, add)
if root.add_value: # to prevent increasing the speed when user pressed "Runprogr" many times.
return
root.add_value = root.after(50, add)
def stop():
if not root.add_value: # to prevent raising Exception when user pressed "Stopbut" button many times.
return
root.after_cancel(root.add_value)
root.add_value = None
runbutt = Button(root, text="Runprogr", command=run)
runbutt.pack()
stopbutt = Button(root, text="Stopbut", command=stop)
stopbutt.pack()
pb = ttk.Progressbar(root, length=300, orient="horizontal")
pb.pack()
root.geometry("300x300")
root.mainloop()
I'm writing a program with Python's tkinter library.
My major problem is that I don't know how to create a timer or a clock like hh:mm:ss.
I need it to update itself (that's what I don't know how to do); when I use time.sleep() in a loop the whole GUI freezes.
Tkinter root windows have a method called after which can be used to schedule a function to be called after a given period of time. If that function itself calls after you've set up an automatically recurring event.
Here is a working example:
# for python 3.x use 'tkinter' rather than 'Tkinter'
import Tkinter as tk
import time
class App():
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(text="")
self.label.pack()
self.update_clock()
self.root.mainloop()
def update_clock(self):
now = time.strftime("%H:%M:%S")
self.label.configure(text=now)
self.root.after(1000, self.update_clock)
app=App()
Bear in mind that after doesn't guarantee the function will run exactly on time. It only schedules the job to be run after a given amount of time. It the app is busy there may be a delay before it is called since Tkinter is single-threaded. The delay is typically measured in microseconds.
Python3 clock example using the frame.after() rather than the top level application. Also shows updating the label with a StringVar()
#!/usr/bin/env python3
# Display UTC.
# started with https://docs.python.org/3.4/library/tkinter.html#module-tkinter
import tkinter as tk
import time
def current_iso8601():
"""Get current date and time in ISO8601"""
# https://en.wikipedia.org/wiki/ISO_8601
# https://xkcd.com/1179/
return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime())
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.now = tk.StringVar()
self.time = tk.Label(self, font=('Helvetica', 24))
self.time.pack(side="top")
self.time["textvariable"] = self.now
self.QUIT = tk.Button(self, text="QUIT", fg="red",
command=root.destroy)
self.QUIT.pack(side="bottom")
# initial time display
self.onUpdate()
def onUpdate(self):
# update displayed time
self.now.set(current_iso8601())
# schedule timer to call myself after 1 second
self.after(1000, self.onUpdate)
root = tk.Tk()
app = Application(master=root)
root.mainloop()
from tkinter import *
import time
tk=Tk()
def clock():
t=time.strftime('%I:%M:%S',time.localtime())
if t!='':
label1.config(text=t,font='times 25')
tk.after(100,clock)
label1=Label(tk,justify='center')
label1.pack()
clock()
tk.mainloop()
You should call .after_idle(callback) before the mainloop and .after(ms, callback) at the end of the callback function.
Example:
import tkinter as tk
import time
def refresh_clock():
clock_label.config(
text=time.strftime("%H:%M:%S", time.localtime())
)
root.after(1000, refresh_clock) # <--
root = tk.Tk()
clock_label = tk.Label(root, font="Times 25", justify="center")
clock_label.pack()
root.after_idle(refresh_clock) # <--
root.mainloop()
I have a simple answer to this problem. I created a thread to update the time. In the thread i run a while loop which gets the time and update it. Check the below code and do not forget to mark it as right answer.
from tkinter import *
from tkinter import *
import _thread
import time
def update():
while True:
t=time.strftime('%I:%M:%S',time.localtime())
time_label['text'] = t
win = Tk()
win.geometry('200x200')
time_label = Label(win, text='0:0:0', font=('',15))
time_label.pack()
_thread.start_new_thread(update,())
win.mainloop()
I just created a simple timer using the MVP pattern (however it may be
overkill for that simple project). It has quit, start/pause and a stop button. Time is displayed in HH:MM:SS format. Time counting is implemented using a thread that is running several times a second and the difference between the time the timer has started and the current time.
Source code on github
from tkinter import *
from tkinter import messagebox
root = Tk()
root.geometry("400x400")
root.resizable(0, 0)
root.title("Timer")
seconds = 21
def timer():
global seconds
if seconds > 0:
seconds = seconds - 1
mins = seconds // 60
m = str(mins)
if mins < 10:
m = '0' + str(mins)
se = seconds - (mins * 60)
s = str(se)
if se < 10:
s = '0' + str(se)
time.set(m + ':' + s)
timer_display.config(textvariable=time)
# call this function again in 1,000 milliseconds
root.after(1000, timer)
elif seconds == 0:
messagebox.showinfo('Message', 'Time is completed')
root.quit()
frames = Frame(root, width=500, height=500)
frames.pack()
time = StringVar()
timer_display = Label(root, font=('Trebuchet MS', 30, 'bold'))
timer_display.place(x=145, y=100)
timer() # start the timer
root.mainloop()
You can emulate time.sleep with tksleep and call the function after a given amount of time. This may adds readability to your code, but has its limitations:
def tick():
while True:
clock.configure(text=time.strftime("%H:%M:%S"))
tksleep(0.25) #sleep for 0.25 seconds
root = tk.Tk()
clock = tk.Label(root,text='5')
clock.pack(fill=tk.BOTH,expand=True)
tick()
root.mainloop()
I am totally new in python GUI and Tkinter. Now i want an entry field where i can change the value or time of self.hide when i will execute this code. that means self.hide value will change from Entry field. In this code this value is statically set to 1 minute. need help from experts.
import Tkinter as Tk
import time
import tkMessageBox
class Window:
def __init__(self):
self.root = None
self.hide = 1 #minutes
self.show = 3 #seconds
def close(self):
self.root.destroy()
return
def new(self):
self.root = Tk.Tk()
self.root.overrideredirect(True)
self.root.geometry("{0}x{1}+0+0".format(self.root.winfo_screenwidth(), self.root.winfo_screenheight()))
self.root.configure(bg='black')
Tk.Label(self.root, text='Hello', fg='white', bg='black', font=('Helvetica', 30)).place(anchor='center', relx=0.5, rely=0.5)
#tkMessageBox.showinfo("Notification", "Your time is up. Time to do next job. . .")
Tk.Button(text = 'Close', command = self.close).pack()
self.root.after(self.show*1000, self.pp)
def pp(self):
if self.root:
self.root.destroy()
time.sleep(self.hide*60)
self.new()
self.root.mainloop()
return
Window().pp()
Try This. It may help you.
from Tkinter import *
import time
root = Tk()
def close():
root.destroy()
def show():
root.deiconify()
button.config(text = 'Close', command = close)
root.after(1000, hide)
def hide():
root.withdraw()
time_to_sleep = set_time_to_sleep.get()
time_to_sleep = float(time_to_sleep)
#print time_to_sleep
time.sleep(time_to_sleep)
show()
set_time_to_sleep = Entry(root)
set_time_to_sleep.pack(side=LEFT)
button = Button(text = 'Set Time', command = hide)
button.pack()
root.mainloop()
To summarise:
Instead of using the sleep function, use the after function. This will not freeze the GUI.
Set the "wait" time of the after function self.Entry.get(). This will collect the info you have put into the Entry.
For more info, look at these links. People smarter than myself give a very clear explication on how to use the functions.
Tkinter, executing functions over time
tkinter: how to use after method