I'm having a function/GUI issue. I'm coding a light function that starts a routine and checks if the time is between 8am and some stop time. This routine starts at 8am and ends at that arbitrary time. The issue is that once I hit start on this routine, the GUI won't let me leave the window with that start button because it's stuck inside the timing routine. I'd really like to be able to set the timer to run in the background and then be able to leave the window of that GUI. It looks like threading is the key to doing that but I'm unsure.
I have the GUI code in a separate file, so as to simplify my work. I haven't explored any GUI interrupt tools yet.
Here is my code
import datetime
from threading import Timer
import tkinter as tk
import time
# =============================================================================
# userInput takes a formatted input and passes it back to main.
# =============================================================================
def userInput():
try:
startTime = datetime.datetime.strptime(input('When would you like the routine to start in HH:MM 24 hour format: '), "%H:%M").time()
print (startTime.strftime("%H:%M"))
except:
print ("Please enter correct time in HHMM format")
try:
redTime = datetime.datetime.strptime(input('When would you to start the red shift in HH:MM 24 hour format: '), "%H:%M").time()
print (redTime.strftime("%H:%M"))
except:
print ("Please enter correct time in HHMM format")
return startTime, redTime
# =============================================================================
# timeComparator is a function which, if the user changes any settings or chooses
# start in the middle of a cycle, implements the correct routine depending on
# where in the cycle it's in. Right now, it's being utitilized to just test.
# The actual function of this will be adjusted later.
# =============================================================================
def timeComparator(startTimered, redTime):
now = datetime.datetime.now().time()
#this obtains the current time
#if statement compares input from
print("The current time is: ", now)
if (now < startTime):
print ("hello human")
elif (now > startTime):
print ("hello plant")
# =============================================================================
# This routine is intended to be controlled by the user in the manual portion
# of the GUI. This receives the start time and returns secs to initiate the
# timer.
# =============================================================================
def manualRoutine(startTime, redTime):
now = datetime.datetime.now().time()
nowSeconds = (((now.hour * 60) + now.minute) * 60) + now.second
startSeconds = ((startTime.hour * 60) + startTime.minute) * 60
secsStart = startSeconds - nowSeconds
redSeconds = ((redTime.hour * 60) + redTime.minute) * 60
nowSeconds = (((now.hour * 60) + now.minute) * 60) + now.second
secsRed = redSeconds - nowSeconds
return secsStart, secsRed
# =============================================================================
# This function references 8am and 8pm and checks to see if the current time is
# between these two time anchors. If it is, it'll implement the lights in the
# while loop. This is meant to be implemented for both the plant life and
# the automatic human routine.
# =============================================================================
def autoRoutine():
now = datetime.datetime.now().time()
autoStart = now.replace(hour=8, minute=0)
stoptime = datetime.datetime.now().time()
autoStop = stoptime.replace(hour=12, minute=29)
#WS2812 code here that the autoStart and autoStop
if (now > autoStart and now < autoStop):
keepprint = False
#
while (keepprint == False):
nowloop = datetime.datetime.now().time()
#nowloop keeps track of the current time through each loop
print("the lights are starting")
time.sleep (1.0)
if (nowloop >= autoStop):
keepprint = True
#this breaks the loop after the stop time
print(autoStart.strftime("%H:%M"))
return autoStart
# =============================================================================
# blueFade is the function call for the beginning of the day light start up and
# midday light continuity. This function will end at the end of the cycle and
# will immediately be followed by the orangeFade() function. Also, this will
# receive the redTime to determine when to stop the function right before the
# red shift
# =============================================================================
def blueFade(redTime):
print("sanity")
keepprint = False
while (keepprint == False):
nowloop = datetime.datetime.now().time()
print("manual routine lights are on")
time.sleep(1.0)
if (nowloop >= redTime):
keepprint = True
print("the manual routine has stopped")
#WS2812 code here
#redTime will be used to end this code before redFade begins
# =============================================================================
# redFade is a function in where the fade from blue to a more reddish hue starts.
# Depending on when the user stated they wanted the red shift to start, this will
# begin at that time and then fade from blue, to a reddish hue, then to completely
# off. This will take exactly 30 minutes
# =============================================================================
def redFade():
print("the red hue is being imprinted")
# =============================================================================
# Main function. Will be used to call all other functions. The
# =============================================================================
if __name__=="__main__":
# autoRoutine()
startTime, redTime = userInput()
timeComparator(startTime, redTime)
secsBlue, secsRed = manualRoutine(startTime, redTime)
bluelights = Timer(secsBlue, lambda: blueFade(redTime))
redlights = Timer(secsRed, redTime)
bluelights.start()
redlights.start()
in the code above, I'd like to run autoRoutine() in the background as well as bluelights and redlights. Right now, if i knew how to run autoRoutine() in the back I could probably fix it up to do both blue and the redlights timer. Thanks in advance.