【发布时间】:2019-08-30 00:13:04
【问题描述】:
我遇到了功能/GUI 问题。我正在编写一个启动例程并检查时间是否在上午 8 点和某个停止时间之间的灯光功能。该例程从上午 8 点开始,并在该任意时间结束。问题是,一旦我在这个例程上点击开始,GUI 不会让我用那个开始按钮离开窗口,因为它卡在计时例程中。我真的很希望能够将计时器设置为在后台运行,然后能够离开该 GUI 的窗口。看起来线程是做到这一点的关键,但我不确定。
我将 GUI 代码放在一个单独的文件中,以简化我的工作。我还没有探索过任何 GUI 中断工具。
这是我的代码
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()
在上面的代码中,我想在后台运行 autoRoutine() 以及蓝灯和红灯。现在,如果我知道如何在后面运行 autoRoutine(),我可能会修复它以同时执行蓝色和红灯计时器。提前致谢。
【问题讨论】:
-
您问题中的代码似乎根本没有使用任何 GUI。也就是说,一般来说,GUI 框架通常是用户事件驱动的,Python 的
tkinter模块也是如此。见Tkinter, executing functions over time。然而,大多数提供了定期检查在“后台”中执行的任意代码状态的方法,例如在单独的线程或进程中。 -
是的,GUI 是在另一个代码中实现的。为了理智,他们分开了。在一天结束时,我只是想保存 startTime 和 redTime
标签: python multithreading time