Need some help in creating a tkinter countdown - python

I am trying to create a timer in tkinter. It count down from set time and then output "Time is up". I have written most of my code. I also have inserted a logging system, so I can work over some errors, which are recorded into a log file.
Code:
from tkinter import *
import logging
logging.basicConfig(filename='timer_err.log',format='%(levelname)s:%(message)s',level=logging.DEBUG)
main = Tk()
main.wm_attributes("-fullscreen",True)
main.wm_attributes("-transparentcolor","darkgreen")
main.title("Timer")
main.config(background="orange")
timerun = 0
comp = 0
secs = DoubleVar()
mins = IntVar()
hrs = IntVar()
def ok():
global timerun
try:
comp = float(float(secs.get())+int(mins.get()*60)+int(hrs.get()*3600))
done.config(state="disabled")
logging.info(("\t{} - Program launched").format(asctime(localtime())))
while timerun < comp:
timerun = clock()
disp.config(state="normal")
disp.insert(0, str(round(comp-timerun, 3)))
main.update()
disp.delete(0, END)
disp.config(state="readonly")
disp.config(state="normal")
disp.insert(0, "Time is up!")
disp.config(state="readonly")
main.update()
def end(self):
main.destroy()
logging.info(("\t{} - Program successfully terminated").format(asctime(localtime())))
main.bind("<Escape>",end)
except Exception as e:
logging.debug(("\t{} - {}").format(asctime(localtime()),str(e)))
logging.warning(("\t{} - {}").format(asctime(localtime()),str(e)))
pass
finally:
logging.info(("\t{} - Program stopped").format(asctime(localtime())))
dispframe = Frame(main, bg="orange")
dispframe.pack(fill="both")
disp = Entry(dispframe, fg="black", bg="lightgray", font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=False, readonlybackground="lightgray", selectforeground="white", selectbackground="navy")
disp.pack(fill="x", pady=12, side="left")
setframe = Frame(main, bg="orange")
setframe.pack(fill="both")
seconds = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=59.5, increment=0.5, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=secs)
seconds.pack(fill="x", pady=12)
minutes = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=59, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=mins)
minutes.pack(fill="x", pady=12)
hours = Spinbox(setframe, fg="red", bg="yellow", from_=0, to=99999, font=("Arial", 100, "bold"), bd=0, state="readonly", takefocus=True, readonlybackground="yellow", buttonbackground="green", selectforeground="white", selectbackground="navy", wrap=True, textvariable=hrs)
hours.pack(fill="x", pady=12)
okframe = Frame(main, bg="orange")
okframe.pack(fill="both")
done = Button(okframe, fg="red", bg="yellow", text="Done", font=("Arial", 100, "bold"), bd=0, activeforeground="red", activebackground="yellow", underline=1, command=ok)
done.pack(fill="x", pady=12)
from time import *
main.mainloop()
Could someone help me to create a "Reset" button, which sets time back to 0?
Or at least give me a slight advice to me on how to do that. Thank you.

Related

tkinter button disappearing

import tkinter
app = tkinter.Tk()
app.geometry("1080x2400")
title = tkinter.Label(
app, text="contador de sets y descansos", font=("Arial", 30))
title.pack(side=tkinter.TOP, fill=tkinter.BOTH)
design = tkinter.Label(app, bg="white")
design.pack(fill=tkinter.BOTH, expand=True)
def series():
label = tkinter.Label(sets, text="completed a set")
label.pack()
sets = tkinter.Button(design, text="sets", padx=40,
pady=20, font=("Arial", 20), command=series)
sets.pack(side=tkinter.LEFT)
def descanso():
label = tkinter.Label(rest, text="completed rest")
label.pack()
rest = tkinter.Button(design, text="rest", padx=40,
pady=20, font=("Arial", 20), command=descanso)
rest.pack(side=tkinter.RIGHT,)
app.mainloop()
I tried to make a button that displays a message on the GUI, but when I press it, the button disappears and what I want is the button to display the message and stay there
Use app for all in line 17, 21, 27 and 31. You had this Button(design,. Should be Button(app,
Here is code:
import tkinter
app = tkinter.Tk()
app.geometry("1080x2400")
title = tkinter.Label(
app, text="contador de sets y descansos", font=("Arial", 30))
title.pack(side=tkinter.TOP, fill=tkinter.BOTH)
design = tkinter.Label(app, bg="white")
design.pack(fill=tkinter.BOTH, expand=True)
def series():
label = tkinter.Label(app, text="completed a set")
label.pack()
sets = tkinter.Button(app, text="sets", padx=40,
pady=20, font=("Arial", 20), command=series)
sets.pack(side=tkinter.LEFT)
def descanso():
label = tkinter.Label(app, text="completed rest")
label.pack()
rest = tkinter.Button(app, text="rest", padx=40,
pady=20, font=("Arial", 20), command=descanso)
rest.pack(side=tkinter.RIGHT,)
app.mainloop()
Output:

Trouble with making a updating loading bar (Label) in Tkinter

I am making a percentage updating Loading bar(Label) which should automatically start when my program has started. When the 'Loading bar' hits 100%, the 'Loading bar' should be removed, and the rest of the program should continue, although when I am starting the program, the window does not respond until about 5 seconds.
number = 0
number1 = str(number)
Labe = tk.Label(root, width=10,bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
Labe.grid(row=0, column=0)
def work():
global number1
Labe['text'] = "Loading" + " " + number1 + "%"
global number
number = number + 1
number1 = str(number)
if number == 102:
root.after(1000)
print("end")
Labe.grid_remove()
num = 101
for x in range(num):
print("He")
root.after(50, work)
root.after(50)
#Adding stuff to root
rootHelloLabel = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
fg="White", font=("Arial Bold", 40), width=48, height=2)
placeholder = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder.grid(row=0, column=0)
rootHelloLabel.grid(row=1, column=0)
placeholder1 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder1.grid(row=2, column=0)
loginButton = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
bg="#71AD90", fg="#D0CFD1", command=login)
loginButton.grid(row=3, column=0)
adminButton = tk.Button(root, pady = 10, padx = 40, text="Admin",
font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
adminButton.grid(row=5, column=0)
I made three small changes and I think it works.
number = 0
number1 = str(number)
Labe = tk.Label(root, width=10,bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
Labe.grid(row=0, column=0)
def work():
global number1
Labe['text'] = "Loading" + " " + number1 + "%"
global number
number = number + 1
number1 = str(number)
if number == 102:
root.after(1000)
print("end")
Labe.grid_remove()
num = 101
for x in range(num):
print("He")
root.after(50, work)
root.after(50)
root.update() # added this so the window displays for one frame
# it's similar to mainloop() but only runs once
#Adding stuff to root
rootHelloLabel = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
fg="White", font=("Arial Bold", 40), width=48, height=2)
placeholder = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder.grid(row=0, column=0)
rootHelloLabel.grid(row=1, column=0)
placeholder1 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder1.grid(row=2, column=0)
loginButton = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
bg="#71AD90", fg="#D0CFD1", command=lambda: login())
loginButton.grid(row=3, column=0) # added lambda function so this only runs when clicked
adminButton = tk.Button(root, pady = 10, padx = 40, text="Admin",
font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
adminButton.grid(row=5, column=0)
root.mainloop() # added this so that the program runs when done (can remove aswell)
I hope this works for you. I didnt quite understand the question but once I added the update() function it worked fine and I realised what you mean by a loading bar. I hope this helps!
You runs 100 times after(50) in for-loop so it can stop program for 5 second. And I don't know if you really need it.
And I would run after(50, work) directly in work
def work():
global number # PEP8: all `global` at the beginning of function
labe['text'] = f"Loading {number}%"
number += 1
if number > 100:
root.update() # to update last text in label because `after(1000)` will block it
root.after(1000)
print("end")
labe.grid_remove()
else:
root.after(50, work)
Full working code (with other changes):
PEP 8 -- Style Guide for Python Code
import tkinter as tk
# --- functions --- # PEP8: all functions directly after imports (and after all classes)
def work():
global number # PEP8: all `global` at the beginning of function
labe['text'] = f"Loading {number}%"
number += 1
if number > 100:
root.update() # to update last text in label because `after(1000)` will block it
root.after(1000)
print("end")
labe.grid_remove()
else:
# run again
root.after(50, work)
def login():
pass
# --- main ---
number = 0
root = tk.Tk()
labe = tk.Label(root, width=10, bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
labe.grid(row=0, column=0)
root_hello_label = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
fg="White", font=("Arial Bold", 40), width=48, height=2)
root_hello_label.grid(row=1, column=0)
placeholder1 = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder1.grid(row=0, column=0)
placeholder2 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder2.grid(row=2, column=0)
login_button = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
bg="#71AD90", fg="#D0CFD1", command=login)
login_button.grid(row=3, column=0)
admin_button = tk.Button(root, pady = 10, padx = 40, text="Admin",
font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
admin_button.grid(row=5, column=0)
# run first time
root.after(50, work)
root.mainloop()
EDIT:
If you need to run with for-loop then you should rather set different times in after(..., work)
for i in range(1, 102):
root.after(50*i, work)
Full working code:
import tkinter as tk
# --- functions --- # PEP8: all functions directly after imports (and after all classes)
def work():
global number # PEP8: all `global` at the beginning of function
labe['text'] = f"Loading {number}%"
number += 1
if number > 100:
root.update() # to update last text in label because `after(1000)` will block it
root.after(1000)
print("end")
labe.grid_remove()
def login():
pass
# --- main ---
number = 0
root = tk.Tk()
labe = tk.Label(root, width=10, bd=1, bg="#ADA5A5", font=("Arial Bold", 36), fg="White")
labe.grid(row=0, column=0)
root_hello_label = tk.Label(root, text="Ordering system, please sign in", bg="#7271AD",
fg="White", font=("Arial Bold", 40), width=48, height=2)
root_hello_label.grid(row=1, column=0)
placeholder1 = tk.Label(root, text="", pady=20, bg="#ACAD71")
placeholder1.grid(row=0, column=0)
placeholder2 = tk.Label(root, text="", pady=70, bg="#ACAD71")
placeholder2.grid(row=2, column=0)
login_button = tk.Button(root, pady=30, padx=80, text="Login", font=("Arial Bold", 27),
bg="#71AD90", fg="#D0CFD1", command=login)
login_button.grid(row=3, column=0)
admin_button = tk.Button(root, pady = 10, padx = 40, text="Admin",
font=("Arial Bold", 27), bg="#71AD90", fg="#D0CFD1")
admin_button.grid(row=5, column=0)
# 102-1 = 101 loops, because it needs to display values 0...100 which gives 101 values
for i in range(1, 102):
root.after(50*i, work)
root.mainloop()
EDIT:
Because after(1000) freezes all GUI for 1 second so it it better to use after(1000, remove_label) to execute other function after 1 second and this doesn't freeze GUI.
def work():
global number
labe['text'] = f"Loading {number}%"
number += 1
if number > 100:
root.after(1000, remove_label)
else:
root.after(50, work)
def remove_label():
print("end")
labe.grid_remove()

Display the location name of the open file in the tkinter window

Very simple, don't be impressed by the size of the code.
I want to do something very simple (well, not for me, since I'm asking for help here) put the location of the open file in the red square on the screen:
Screen
import tkinter as tk
from tkinter.filedialog import askopenfilename
from tkinter import messagebox
def OpenFile_AntiDuplicate():
global antiduplicate_file
mainframe = tk.Frame(bg='#1c2028')
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir = tk.Label(mainframe, text=antiduplicate_file).pack()
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
print("Non-existent file")
def RUN_AntiDuplicate():
try:
with open(antiduplicate_file,'r') as UseFile:
print(antiduplicate_file)
except:
error1 = tk.messagebox.showerror("ERROR", "No files exist!")
#----------------------------------------------------------
class HoverButton(tk.Button):
def __init__(self, master, **kw):
tk.Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
self['background'] = self['activebackground']
def on_leave(self, e):
self['background'] = self.defaultBackground
#----------------------------------------------------------
def Anti_Duplicate():
mainframe = tk.Frame(bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='nsew')
bouton_1 = HoverButton(mainframe, font=("Arial", 10), text="Back",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#CF3411',
relief='ridge', command=mainframe.destroy)
bouton_1.place(x=520, y=300)
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = OpenFile_AntiDuplicate)
open_button.place(x=284.3, y=200, anchor='n')
run_button = HoverButton(mainframe, font=("Arial", 20), text="RUN",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#11CF6D',
relief='ridge', command = RUN_AntiDuplicate)
run_button.place(x=50, y=330, anchor='s')
bouton_2 = tk.Button(mainframe, font=("Arial", 10),
text="The purpose of this tool is to remove duplicate lines from a text file.",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground= '#202124', activeforeground='#1195cf', relief='sunken')
bouton_2.place(relx=.5, y=50, anchor='n')
bouton_1 = tk.Button(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#202124', fg='#1195cf', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf', relief='sunken')
bouton_1.pack(side= "top", padx= 5, pady=5, ipadx= 30, anchor="n")
#----------------------------------------------------------
def main_menu():
root = tk.Tk()
screenn_x = int(root.winfo_screenwidth())
root.config(background='#1c2028')
screenn_y = int(root.winfo_screenheight())
root.title("ComboKit v0.0.1")
root.minsize(570, 340)
root.resizable(0,0)
windowss_x = 570
windowss_y = 340
possX = (screenn_x // 2) - (windowss_x // 2)
possY = (screenn_y // 2) - (windowss_y // 2)
geoo = "{}x{}+{}+{}".format(windowss_x, windowss_y, possX, possY)
root.geometry(geoo)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
mainframe = tk.Frame(root, bg='#1c2028')
mainframe.grid(row=0, column=0, sticky='n')
main_fusion_bouton = HoverButton(mainframe, font=("Arial", 15), text="Fusion",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_fusion_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 10, anchor="n")
main_antiduplicate_bouton = HoverButton(mainframe, font=("Arial", 15), text="Anti-Duplicate",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=Anti_Duplicate)
main_antiduplicate_bouton.pack(side= "left", padx= 5, pady=5, ipadx= 30)
main_split_button = HoverButton(mainframe, font=("Arial", 15), text="Split",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command=None)
main_split_button.pack(side= "left", padx= 5, pady=5, ipadx= 19, anchor="n")
root.mainloop()
main_menu()
So here's my code allows you to use 3 tools:
"Split" / "Anti-Duplicate" / "Merge"
At the moment I'm working on the "Anti-Duplicate" so it's on this Frame() where the text should be displayed.
I've already done everything, even the button to open the file explorer, but for the moment the location of the file is only displayed in the cmd.
Thank you very much!
The location of the file does not show up because you created a new frame to hold the label fichier_dir inside OpenFile_AntiDuplicate() and you did not call any layout function on the frame, so the frame will not be shown.
Better create the label fichier_dir inside Anti_Duplicate() and pass it to OpenFile_AntiDuplicate() function:
def Anti_Duplicate():
...
fichier_dir = tk.Label(mainframe, bg='#1c2028', fg='white')
fichier_dir.place(relx=0.5, y=170, anchor='n')
open_button = HoverButton(mainframe, font=("Arial", 10), text="Open File..",
background='#000000', fg='white', borderwidth=2,
activebackground='#202124', activeforeground='#1195cf',
relief='ridge', command = lambda: OpenFile_AntiDuplicate(fichier_dir))
...
And update OpenFile_AntiDuplicate(...):
def OpenFile_AntiDuplicate(fichier_dir):
global antiduplicate_file
antiduplicate_file = askopenfilename(initialdir="/",
filetypes =(("Text file", "*.txt"),("All files","*.*")),
title = "Open text file"
)
fichier_dir['text'] = antiduplicate_file
...

How to update Labels in tkinter?

I'm trying to create a program in where you put a word in a box, press add, and this word goes to a list, which is also displayed on the right side. When I press the forward button the first thing on the list is deleted. Problem is I can't get the labels to update when I press the buttons / edit the list.
from tkinter import *
root = Tk()
root.title('Speakers List')
root.minsize(800, 600)
speakers = ['none']
spe = speakers[0]
def add():
if spe == 'none':
speakers.insert(0, [s])
e.delete(0, END)
spe.config(text=speakers[0])
else:
speakers[-2] = [s]
e.delete(0, END)
spe.config(text=speakers[0])
return
def forward():
if len(speakers) is 0:
return
else:
del speakers[0]
spe.config(text=speakers[0])
return
entry = StringVar()
e = Entry(root, width=30, font=("Arial", 20), textvariable=entry)
e.grid(row=0, sticky=W)
s = e.get()
button1 = Button(root, padx=10, pady=10, bd=5, text='Add', fg='black', command=add)
button1.grid(row=0, column=1)
button2 = Button(root, padx=10, pady=10, bd=5, text='Next', fg='black', command=forward)
button2.grid(row=1, column=1)
n = Label(root, font=("Arial", 35), bd=2, text=spe)
n.grid(row=1, sticky=W)
listdisplay = Label(root, font=('Arial', 20), text=speakers)
listdisplay.grid(row=0, column=10)
root.mainloop()
Is this the sort of thing you were looking for ?
from tkinter import *
root = Tk()
root.title('Speakers List')
root.minsize(800, 600)
speakers = ['50']
spe = speakers[0]
def add():
entry=e.get()
speakers.append(entry)
listdisplay.config(text=speakers)
return
def forward():
if len(speakers) is 0:
return
else:
del speakers[0]
listdisplay.config(text=speakers)
spe=speakers[0]
n.config(text=spe)
return
entry = StringVar()
e = Entry(root, width=30, font=("Arial", 20), textvariable=entry)
e.grid(row=0, sticky=W)
s = e.get()
button1 = Button(root, padx=10, pady=10, bd=5, text='Add', fg='black',command=add)
button1.grid(row=0, column=1)
button2 = Button(root, padx=10, pady=10, bd=5, text='Next', fg='black',command=forward)
button2.grid(row=1, column=1)
n = Label(root, font=("Arial", 35), bd=2, text=spe)
n.grid(row=1, sticky=W)
listdisplay = Label(root, font=('Arial', 20), text=speakers)
listdisplay.grid(row=0, column=10)
root.mainloop()
If so:
You create a list and then you use the append function to add an item to it. The rest was pretty much right.

how to show run time and loops per hour

I have a script which operates gpio's then loops until the loop is broken by a tkinter button, id like to see how many loops its doing per hour. im already able to see how many loops its done with a global variable but cannot work out nor find out how to make it show the current run time and how many loops per hour.. please help..
Here's the MCVE
import Tkinter as tk
root = tk.Tk()
from Tkinter import *
import time
import datetime
root.geometry("748x150")
root.title("Countdown Tester")
run_counter = 0
ts = datetime.datetime.now()
tf = datetime.datetime.now()
te = tf - ts
def _1():
label2["text"] = "1"
label2.config(bg='orange', fg='black')
root.update_idletasks()
time.sleep(1)
def _0():
label2["text"] = "0"
label2.config(bg='orange', fg='black')
root.update_idletasks()
time.sleep(1)
global run_counter
run_counter += 1
root.update_idletasks()
label6["text"] = run_counter
label7["text"] = run_counter# *********** Id like to have the run times per hour listed here
label8["text"] = te# *********** Id like to have the total run time listed here
root.update_idletasks()
canvas = Canvas(width=720, height=150, bg='black')
canvas.grid(rowspan=26, columnspan=20, sticky='W,E,N,S')
label2 = Label(root, width=11, font='-weight bold', background='black', foreground='white')
label2.grid(padx=5, pady=10, row=0, column=0, sticky='W,E,N,S')
label6 = Label(root, text=run_counter, width=11, font='-weight bold', background='white', foreground='black')
label6.grid(padx=5, pady=10, row=0, column=1, sticky='W,E,N,S')
label7 = Label(root, text=run_counter, width=11, font='-weight bold', background='white', foreground='black')
label7.grid(padx=5, pady=10, row=1, column=1, sticky='W,E,N,S')
label8 = Label(root, text=te, width=11, font='-weight bold', background='white', foreground='black')
label8.grid(padx=5, pady=10, row=1, column=0, sticky='W,E,N,S')
#root.resizable(width=FALSE, height=FALSE)
#timer()
while 1:
try:
_1()
_0()
root.update()
except KeyboardInterrupt:
break
root.mainloop()
for some reason this MCVE reports an error on _1() when quit

Categories