我遇到功能/ GUI问题。我正在编写一个轻量函数,该函数将启动例程并检查时间是否在8am至某个停止时间之间。该例程在上午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(),我可能可以将其修复为同时执行蓝色和红色指示灯。预先感谢。
答案 0 :(得分:0)
您可以通过实现threading.Thread()
在后台运行事物,该while True:
传递任何需要的参数。在大多数情况下,我发现.join()
循环效果最好,因此线程将永远运行,但是在某些情况下,您可能希望将while some_global_variable == 1
线程返回到主执行流程中。我通常使用import threading # standard library, no pip-install
import tkinter as tk
import time
start = time.time()
win = tk.Tk()
label = tk.Label()
label.grid()
def worker_function():
while True:
now = time.time()
elapsed = now - start
label.configure(text='{:5.2}'.format(elapsed))
t = threading.Thread(target=worker_function, args=[])
t.daemon = True
t.start() # our thread will run until the end of the assigned function (worker_function here)
# this will never end because there is a while True: within worker_function
win.mainloop()
进行此操作,然后可以从函数外部进行编辑,或者仅等待线程自己到达分配的函数的末尾。主要流程如下所示:
def worker_function(a, b, c, d):
此外,您可以在提供的[]中为线程提供参数(即使只有1个参数,它也需要一个列表)。因此,如果我们的功能是:
t = threading.Thread(target=worker_function, args=[a, b, c, d])
我们的线程将创建为:
target=worker_function
还要注意,它是target=worker_function()
而不是@KafkaListener(topics = "input")
@SendTo("output")
public ConsumerRecords consume(ConsumerRecords records) {
// Do things
return records;
}