To perform the timer task using python - python

I want reset the timer to 0 when it reaches to 8 and should sleep for 5 secs showing timer value as 0 and again restart from zero and repeat.
when linemode == 'dashed': But with my current code when it reaches 8 it displays 8, where i want to display 0 for 5 secs. I have posted full code snippet as well as piece of code where code has to perform expectation. Thanks in Advnc
code Snippet:-
if ton > ontym:
if linemode == 'dashed':
counter=0
lbl['text']='00'
sleep(offtym)
ton=-1
lbl.after(1000, count)
else:
lbl.after(1000, count)
else:
lbl.after(1000, count)
Full code Snippet:-
#!/usr/bin/env python
from Tkinter import Tk,Label,Button
import rospy
from time import sleep
from PIL import Image, ImageTk
ws = Tk()
#ws.geometry('400x450+1000+300')
ws.title('Stopwatch')
ws.attributes('-fullscreen', True)
ws.config(bg='#efb570')
#ws.resizable(0,0)
ontym=8
offtym=5
ton=-1
linemode = 'dashed'
counter = 0
running = False
def counter_label(lbl):
def count():
if running:
global counter,offtym,ontym,ton,linemode
if counter == 0:
display="00"
else:
display='0' +str(counter)
if counter > 9:
display = str(counter)
lbl['text']=display
counter += 1
ton += 1
if ton > ontym:
if linemode == 'dashed':
counter=0
lbl['text']='00'
sleep(offtym)
ton=-1
lbl.after(1000, count)
else:
lbl.after(1000, count)
else:
lbl.after(1000, count)
count()
def StartTimer(lbl):
global running
running=True
counter_label(lbl)
start_btn['state']='disabled'
stop_btn['state']='normal'
def StopTimer():
global running
start_btn['state']='normal'
stop_btn['state']='disabled'
running = False
pic=Image.open("/home/nooduupachuu/catkin_ws/src/gui_sample/scripts/abc.png")
tkImg=ImageTk.PhotoImage(pic)
lbl1=Label(ws, image=tkImg, bg='#efb570')
lbl1.image=tkImg
lbl1.place(x=405, y=50)
lbl = Label(ws, text="00", fg="black", bg='#efb570', font="Verdana 80 bold")
label_msg = Label(ws, text="seconds", fg="black", bg='#efb570', font="Verdana 30 bold")
lbl.place(x=585, y=315)
label_msg.place(x=570, y=445)
start_btn=Button(ws, text='START', width=9, bd=2, font=("Arial Bold", 12), command=lambda:StartTimer(lbl))
stop_btn = Button(ws, text='STOP', width=9, bd=2, font=("Arial Bold", 12), state='disabled', command=StopTimer)
start_btn.place(x=535, y=700)
stop_btn.place(x=675, y=700)
ws.mainloop()

Related

Why does my python code not continue execution once my function "executelogin()" has been executed?

I am encountering a problem where my code does NOT continue execution of the rest of the program once my called function, completes execution.
Here is the function that is being called:
def executelogin():
global initiate_game_window
global checker
counter = 1
while counter < 4:
global login_tk, game, us1_entry, us2_entry, us1_pwd_entry, us2_pwd_entry
login_tk = Tk(screenName="Login - RollADie")
titlelabel = Label(text="Welcome to rollaDie", font=('Open Sans', '20'))
titlelabel.grid(column=0, row=0, sticky=NSEW)
sublabel = Label(text="Login Below: ", font=('Open Sans', '10'))
sublabel.grid(column=0, row=1, sticky=NSEW)
us1_label = Label(text="User 1:")
us1_label.grid(row=2, column=0, sticky=NSEW)
us1_entry = Entry(width=10, textvariable=us1_uname)
us1_entry.grid(row=3, column=0, sticky=NSEW)
us1_pwd_label = Label(text="Password:")
us1_pwd_label.grid(row=4, column=0, sticky=NSEW)
us1_pwd_entry = Entry(width=10, show="*", textvariable=us1_pwrd)
us1_pwd_entry.grid(row=5, column=0, sticky=NSEW)
us2_label = Label( text="User 2:")
us2_label.grid(row=6, column=0, sticky=NSEW)
us2_entry = Entry(width=10, textvariable=us2_uname)
us2_entry.grid(row=7, column=0, sticky=NSEW)
us2_pwd_label = Label(text="Password:")
us2_pwd_label.grid(row=8, column=0, sticky=NSEW)
us2_pwd_entry = Entry(width=10, show="*", textvariable=us2_pwrd)
us2_pwd_entry.grid(row=9, column=0, sticky=NSEW)
def get_credentials():
global us1_entry, us2_entry, us1_pwd_entry, us2_pwd_entry, top_login
us1_uname = us1_entry.get()
us1_pwrd = us1_pwd_entry.get()
us2_uname = us2_entry.get()
us2_pwrd = us2_pwd_entry.get()
print(us1_uname, us1_pwrd, us2_uname, us2_pwrd)
global credentials
credentials = [us1_uname, us1_pwrd, us2_uname, us2_pwrd]
top_login.destroy()
global top_login
top_login = tk.Toplevel()
top_login.geometry('1x1+0+0')
top_login.overrideredirect(True)
submit_button = Button(text="Submit", command=get_credentials)
submit_button.grid(row=10, column=0, sticky=NSEW)
top_login.wait_window(top_login)
us1_auth = False
us2_auth = False
if login(credentials[0], credentials[1]) == True:
us1_auth = True
else:
pass
if login(credentials[2], credentials[3]) == True:
us2_auth = True
else:
pass
if us1_auth == True:
if us2_auth == True:
print("Auth POS")
messagebox.showinfo(message="AUTHORISED")
login_tk.destroy()
break
else:
print("User 2 AUTH NEG")
messagebox.showinfo(message="User 2 Denied")
counter += 1
if counter > 3:
messagebox.showinfo(message="MAX ATTEMPTS")
quit()
continue
else:
print("AUTH USER 1 NEG")
messagebox.showinfo(message="USER 1 NOT AUTHORISED")
counter += 1
if counter > 3:
messagebox.showinfo(message="MAX ATTEMPTS")
quit()
continue
login_tk.mainloop()
I am not sure why this is not continuing on with the rest of the code as expected.
I'd appreciate any help.
For further reference, there is another Tk object in this file, which is initiated later down.
Thanks
şehzade Muhammad Amen Ehsan
Edit:
Below this function is the following code:
top = None
top_roll2 = None
faces = {'1':'\u2680', '2':'\u2681', '3':'\u2682', '4':'\u2683', '5':'\u2684', '6':'\u2685'}
root = Tk(className='RollADice', screenName='RollADice')
title = Label(text='RollADice by. Amen', font=('Open Sans', '20')).grid(row=0, column=0, sticky=NSEW)
round_teller = Label(text='Currently: Round {0}'.format(roundnum))
round_teller.grid(row=1, column=0, sticky=NSEW)
dicelabel = Label(root)
my 2 cents: you are creating a Tk instance within that function, and hence you have an infinite loop that wont finish until you exit from it; that is, until you exit from the login_tk mainloop.

Call a fonction from message box Tkinter

I want to call the fonction (submit) after clicking on the message box. With this code I have to reclick on button everytime after the messagebox but would appreciate if the timer launch automatically after clicking on the message box.
If anyone have a clue I will appreciate.
The following code :
import time
from tkinter import *
root = Tk()
root.resizable(width=False, height=False)
root.geometry("300x250")
root['background']='#39E5F9'
root.title("Time To Drink Water")
minute = StringVar()
second = StringVar()
minute.set("45")
second.set("00")
minuteEntry = Entry(root, width=3, font=("Arial", 35, ""),
textvariable=minute,justify='center')
minuteEntry.place(x=50, y=60)
secondEntry = Entry(root, width=3, font=("Arial", 35, ""),
textvariable=second,justify='center')
secondEntry.place(x=170, y=60)
def submit():
# stored in here : 2700 = 45 mins
temp = 2700
while temp > -1:
# divmod(firstvalue = temp//60, secondvalue = temp%60)
mins, secs = divmod(temp, 60)
if mins > 60:
hours, mins = divmod(mins, 60)
minute.set("{0:2d}".format(mins))
second.set("{0:2d}".format(secs))
root.update()
time.sleep(1)
if (temp == 0):
messagebox.showinfo("Time Countdown", "Time To Drink !")
temp -= 1
def go():
btn = Button(root, text='Goodbye dehydration!', bd='6',
command=submit)
btn.place(x=90, y=160)
go()
root.mainloop()
messagebox is waiting for your click so you can run submit() after messagebox and it will run it after clicking in messagebox
But you shouldn't use while and sleep because it may freeze GUI (in any framework, and in any language). You can use root.after(1000, function) to run function again after 1000ms (1s) and it will work as sleep and while together.
import time
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import messagebox
# --- functions --- # PEP8: all functions before main code
def submit():
update_counter(2700)
def update_counter(temp):
if temp > -1: # `if` instead of `while` because `after` will work as loop
# divmod(firstvalue = temp//60, secondvalue = temp%60)
mins, secs = divmod(temp, 60)
if mins > 60:
hours, mins = divmod(mins, 60)
minute.set("{:02d}".format(mins)) # use `:02` to get `09` instead of ` 9` (with space)
second.set("{:02d}".format(secs))
temp -= 1
root.after(1000, update_counter, temp) # run again after 1000ms
else:
messagebox.showinfo("Time Countdown", "Time To Drink !")
root.after(0, update_counter, 2700) # run again after 0ms
#update_counter(2700) # run again
# --- main --- # PEP8: `lower_case_names` for variables
running = False
temp = 2700
root = tk.Tk()
minute = tk.StringVar(root)
second = tk.StringVar(root)
minute.set("45")
second.set("00")
minute_entry = tk.Entry(root, width=3, textvariable=minute, font=("Arial", 35, ""), justify='center')
minute_entry.grid(row=0, column=0)
second_entry = tk.Entry(root, width=3, textvariable=second, font=("Arial", 35, ""), justify='center')
second_entry.grid(row=0, column=1)
btn = tk.Button(root, text='Goodbye dehydration!', command=submit)
btn.grid(row=1, column=0, columnspan=2)
root.mainloop()
PEP 8 -- Style Guide for Python Code
There is other problem. You can click button two times and it will run two update_counter() at the same time. It may need to disable button, or you would have to use boolean variable - ie. running = False - to control if it has to run update_counter() or not.

timer function with global variable not counting down

so I am made a function that counts down, I have it count down from number n minus 1, it works but if I add a global variable (I named it flag, if flag == True then I want it to count down. if flag == False the I want timer to stop, I need that this variable to be global b/c I have another button that changes flag to False if pressed called pause. however my function does not display 5 , 4, 3, 2,1 every second. it just displays 5 now, when I add the global variables. and it only happens if I added global variables. please tell me what need to change. I am open to the idea of changing the way, I pause and play this function, if there is a different way to do so.
flag = True
holder_for_time = 6
# timer for next ball
def update_timer_countdown(n):
global flag
if flag == True and n != "1":
n = int(n)
n -= 1
n = str(n)
timer.config(
text="Next draw in:" + n + "s", padx=5, pady=45, font=("Helvetica", 17)
)
return timer.after(1000, update_timer_countdown, 6) # this step does not come through
elif flag == True and n == "1":
return update_timer_countdown(6)
elif flag == False:
global holder_for_time
holder_for_time = n
timer = Label(root, text="Next draw in:" + "s", padx=5, pady=45, font=("Helvetica", 17))
timer.grid(row=1, column=1, columnspan=2, rowspan=5, sticky="nsew")
update_timer_countdown(6)
I have edit few lines of code, and now it works how you want
here is the code
from tkinter import *
flag = True
holder_for_time = 6
n = 6
# timer for next ball
def update_timer_countdown():
global flag, n
if flag:
if n != 0:
n -= 1
timer.config(
text=f"Next draw in: {n}s", padx=5, pady=45, font=("Helvetica", 17)
)
return timer.after(1000, update_timer_countdown) # this step does not come through
else:
global holder_for_time
holder_for_time = n
def _command():
global flag
flag = not flag
if flag:
pause['text'] = "pause"
else:
pause['text'] = "resume"
update_timer_countdown()
def restart_command():
global flag, n
flag = True
n = 6
update_timer_countdown()
root = Tk()
timer = Label(root, text="Next draw in:", padx=5, pady=45, font=("Helvetica", 17))
timer.grid(row=1, column=1, columnspan=2, rowspan=5, sticky="nsew")
update_timer_countdown()
pause = Button(root, text="pause", font=("Helvetica", 10), command=_command)
pause.grid(row=0, column=0)
restart = Button(root, text="Restart", font=("Helvetica", 10), command=restart_command)
restart.grid(row=0, column=1)
root.mainloop()

use a while true loop while the code below is still running (python)

Im making this game called:
IDLE PEN ,(MAKE PENS)
and every 1 second i get a bonus pen
how i get a bonus pen is doing this
Import time
While true
make a pen()
time.sleep(1)
but i have some code under the while true loop.
the code under the while true loop is like buttons to
upgrade the pens or make a pen
So how do i make the code under the while true loop work?
This is my game im happy for anyone to copy it
its not ready yet
import functools
import tkinter
import tkinter.messagebox
import time
from random import seed
from random import randint
# eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
window = tkinter.Tk()
window.title('Idle Pen')
def print_pen(number: int):
return f"Pens: {number}"
class pencount:
def __init__(self):
self.pencount = 0
self.text = tkinter.Text(height=1, width=30)
self.text.insert("1.0", print_pen(0))
self.text['state'] = 'disabled'
self.text.pack()
def changepencount(self, count):
if self.pencount + count < 0:
return
self.pencount = self.pencount + count
self.text['state'] = 'normal'
self.text.delete("1.0", "end")
self.text.insert("1.0", print_pen(self.pencount))
self.text['state'] = 'disabled'
self.text.pack()
pen = pencount()
changepenup = functools.partial(pen.changepencount, 1)
B = tkinter.Button(window, text="Make Pen", command=changepenup)
changependown = functools.partial(pen.changepencount, -100)
A = tkinter.Button(window, text='Penmaker', command=changependown)
Q = tkinter.Button(window, text="Quit", command=window.destroy)
U = tkinter.Button
# eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
B.pack()
A.pack()
Q.pack()
window.mainloop()
You could use threading to run your loop in separated thread and then main thread may run tkitner
OR you can use tkinter function after() (instead of while True) to run function with delay and this function should use again after() to run itself.
import tkinter as tk
# --- functions ---
def update():
global value
value += 1
text = f'make penny: {value}'
print(text)
label['text'] = text
# run again after 1s (1000ms)
root.after(1000, update)
# --- main ---
value = 0
root = tk.Tk()
label = tk.Label(root, text="make penny: 0")
label.pack()
button = tk.Button(root, text="Exit", command=root.destroy)
button.pack()
# run first time after 1s (1000ms)
root.after(1000, update)
root.mainloop()

Tkinter - For Loop too early

I have a code for a "Magic Mirror" where I want to display clock, title and news (in Japanese).
I have a whole code that works fine with a news code inside it - In Tkinter loop - news code takes whole messages with json, hide everything except of title, put them to the list and shows loop through it to show messages one by one. It works well in terminal, but I have a struggles to put it into Tkinter window loop - It loops through it and shows only the last news subject - I would like them all, one every 10 seconds, or so... Is there a way to do it please? I will be happy for every answer, thanks.
Here is THE Code
import tkinter as tk
from tkinter import *
startupscreen = tk.Tk()
startupscreen.title('Magic Mirror: Python Mod')
welcometext = tk.Label(startupscreen, font = ('caviar dreams', 40), bg='black', fg='white')
startupscreen.configure(background='black')
startupscreen.overrideredirect(True)
welcometext.config(text='Mirror: Vuoristo Mod')
welcometext.pack(side=LEFT, padx= 120, pady=80)
# Gets the requested values of the height and widht.
windowWidth = startupscreen.winfo_reqwidth()
windowHeight = startupscreen.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(startupscreen.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(startupscreen.winfo_screenheight()/2 - windowHeight/2)
# Positions the window in the center of the page.
startupscreen.geometry("+{}+{}".format(positionRight, positionDown))
startupscreen.update()
import time
from newsapi import NewsApiClient
import os
import feedparser
import json
from time import sleep
decrypt = list()
global iteration
global timecount
global repull
global sleep
iteration = 0
timecount = 0
repull = 0
sleep = 0
while True:
def tick(time1=''):
time2 = time.strftime("%H")
if time2 != time1:
time1 = time2
clock_frame.config(text=time2)
clock_frame.after(200, tick)
def tickk(time3=''):
time4 = time.strftime(":%M:%S")
if time4 != time3:
time3 = time4
clock_frame2.config(text=time4)
clock_frame2.after(200, tickk)
#This function waits for a certain amount of 'tocks' and then initiates 'newsheader' -function
def tock():
global timecount
global repull
global sleep
global decrypt
newstitle.after(200, tock)
if timecount < 20:
timecount +=1
else:
timecount = 0
newsheader()
if repull < 200:
repull +=1
if sleep < 800:
sleep+=1
else:
sleep = 0
motiondetector()
#This function iterates over the news headlines. Iteration is the news number, 'itemlist' brings out only the title.
def newsheader():
url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
d = feedparser.parse(url)
news = list()
for i, entry in enumerate(d.entries, 1):
p = entry.published_parsed
sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)
tmp = {
"title": entry.title,
#"link": entry.link,
"sortkey": sortkey
}
news.append(tmp)
news = sorted(news, key=lambda x: x['sortkey'])
myDict = {}
# HERE IS THE PROBLEM, I HAVE LIKE 30 news IN `frequency`, BUT IT SHOWS ONLY LAST ONE
for d in news:
c = d['title']
myDict[c] = myDict.get(c,0)+1
frequency = myDict.keys()
frequency = list(frequency)
for x in range(len(frequency)):
source.config(text=str(frequency[x]))
x += 1
root = tk.Tk()
root.title('Mirror')
lab = Label(root, text=" 日本", font = ('', 40), bg='black', fg='white')
lab.pack(anchor=SW, fill=X, padx=45)
masterclock = tk.Label(root)
masterclock.pack(anchor=NW, fill=X, padx=45)
masterclock.configure(background='black')
clock_frame = tk.Label(root, font = ('caviar dreams', 130), bg='black', fg='white')
clock_frame.pack(in_=masterclock, side=LEFT)
clock_frame2 = tk.Label(root, font = ('caviar dreams', 70), bg='black', fg='white')
clock_frame2.pack(in_=masterclock, side=LEFT, anchor = N, ipady=15)
newstitle = tk.Label(root, font = ('caviar dreams', 30), bg='black', fg='white')
newstitle.pack(side=BOTTOM, anchor=W, fill=X)
source = tk.Label(root, font = ('caviar dreams', 20), bg='black', fg='white')
source.pack(side=BOTTOM, anchor=W, fill=X)
newsheader()
tick()
tickk()
tock()
root.attributes("-fullscreen", True)
root.configure(background='black')
startupscreen.destroy()
root.mainloop()
This code use function display_next_item to get next element from list frequency and put in Label. And it use after() to do it again after 1 second. You can set 10 seconds but for test I use smaller value.
For tests I also had to removed fullscreen and newsapi (which I don't have installed)
import tkinter as tk
from tkinter import *
startupscreen = tk.Tk()
startupscreen.title('Magic Mirror: Python Mod')
welcometext = tk.Label(startupscreen, font = ('caviar dreams', 40), bg='black', fg='white')
startupscreen.configure(background='black')
startupscreen.overrideredirect(True)
welcometext.config(text='Mirror: Vuoristo Mod')
welcometext.pack(side=LEFT, padx= 120, pady=80)
# Gets the requested values of the height and widht.
windowWidth = startupscreen.winfo_reqwidth()
windowHeight = startupscreen.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(startupscreen.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(startupscreen.winfo_screenheight()/2 - windowHeight/2)
# Positions the window in the center of the page.
startupscreen.geometry("+{}+{}".format(positionRight, positionDown))
startupscreen.update()
import time
#from newsapi import NewsApiClient
import os
import feedparser
import json
from time import sleep
decrypt = list()
global iteration
global timecount
global repull
global sleep
iteration = 0
timecount = 0
repull = 0
sleep = 0
while True:
def tick(time1=''):
time2 = time.strftime("%H")
if time2 != time1:
time1 = time2
clock_frame.config(text=time2)
clock_frame.after(200, tick)
def tickk(time3=''):
time4 = time.strftime(":%M:%S")
if time4 != time3:
time3 = time4
clock_frame2.config(text=time4)
clock_frame2.after(200, tickk)
#This function waits for a certain amount of 'tocks' and then initiates 'newsheader' -function
def tock():
global timecount
global repull
global sleep
global decrypt
newstitle.after(200, tock)
if timecount < 20:
timecount +=1
else:
timecount = 0
newsheader()
if repull < 200:
repull +=1
if sleep < 800:
sleep+=1
else:
sleep = 0
motiondetector()
#This function iterates over the news headlines. Iteration is the news number, 'itemlist' brings out only the title.
def newsheader():
url = 'https://news.google.com/rss?hl=ja&gl=JP&ceid=JP:ja'
d = feedparser.parse(url)
news = list()
for i, entry in enumerate(d.entries, 1):
p = entry.published_parsed
sortkey = "%04d%02d%02d%02d%02d%02d" % (p.tm_year, p.tm_mon, p.tm_mday, p.tm_hour, p.tm_min, p.tm_sec)
tmp = {
"title": entry.title,
#"link": entry.link,
"sortkey": sortkey
}
news.append(tmp)
news = sorted(news, key=lambda x: x['sortkey'])
myDict = {}
for d in news:
c = d['title']
myDict[c] = myDict.get(c,0)+1
global frequency
frequency = list(myDict.keys())
def display_next_item():
global frequency
global next_index
next_index += 1
if next_index >= len(frequency):
next_index = 0
source.config(text=str(frequency[next_index]))
root.after(1000, display_next_item)
frequency = [] # value at start
next_index = 0 # value at start
root = tk.Tk()
root.title('Mirror')
lab = Label(root, text=" 日本", font = ('', 40), bg='black', fg='white')
lab.pack(anchor=SW, fill=X, padx=45)
masterclock = tk.Label(root)
masterclock.pack(anchor=NW, fill=X, padx=45)
masterclock.configure(background='black')
clock_frame = tk.Label(root, font = ('caviar dreams', 130), bg='black', fg='white')
clock_frame.pack(in_=masterclock, side=LEFT)
clock_frame2 = tk.Label(root, font = ('caviar dreams', 70), bg='black', fg='white')
clock_frame2.pack(in_=masterclock, side=LEFT, anchor = N, ipady=15)
newstitle = tk.Label(root, font = ('caviar dreams', 30), bg='black', fg='white')
newstitle.pack(side=BOTTOM, anchor=W, fill=X)
source = tk.Label(root, font = ('caviar dreams', 20), bg='black', fg='white')
source.pack(side=BOTTOM, anchor=W, fill=X)
newsheader()
tick()
tickk()
tock()
display_next_item() # <- start displaying
#root.attributes("-fullscreen", True)
root.configure(background='black')
startupscreen.destroy()
root.mainloop()
You need to use threading. And you can create a Repeating class or a Background class to perform your news reading every 10 seconds like this.

Categories

Resources