当前位置: 首页 > 知识库问答 >
问题:

在GUI后台运行函数

衡子琪
2023-03-14

我有一个函数/GUI问题。我正在编码一个轻函数,它开始一个例程,并检查时间是否在上午8点和一些停止时间之间。这个例程从早上8点开始,在那个任意的时间结束。问题是,一旦我点击这个例程的开始,图形用户界面就不会让我带着开始按钮离开窗口,因为它卡在定时例程里面了。我真的希望能够设置计时器在后台运行,然后能够离开图形用户界面的窗口。看起来线程是做到这一点的关键,但我不确定。

我将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(),我可能会把它修复成蓝色和红灯计时器。提前感谢。

共有1个答案

长孙景焕
2023-03-14

通过实现线程,可以在后台运行。线程(),传递任何需要的参数。大多数时候,我发现一个而True:循环工作得最好,所以线程将永远运行,但是有一些实例你可能想要。加入()线程回到你的主执行流。我通常在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()

此外,您可以在提供的[]内为线程提供参数(即使只有1个参数,它也需要一个列表)。如果我们的功能是:

def worker_function(a, b, c, d):

我们的线程将创建为:

t = threading.Thread(target=worker_function, args=[a, b, c, d])

还要注意它是Target=worker_function而不是Target=worker_function()

 类似资料:
  • 我有工人班 还有一个窗口类,它使用tkinter 但是,即使长任务()是在一个单独的线程中运行,我的GUI冻结-为什么? 我的目标是更新窗口中的一个进度条,而长任务()正在运行。长任务()内部更新一个数字,范围从0到100。 问题:在longTask()运行时,如何实现这一点并防止GUI冻结? 注意:显然线程不是在我调用t.start()时启动的,而是在我通过t=线程启动线程时启动的。线程...

  • 我目前正在尝试为我的程序创建一个启动屏幕,因为启动需要一些时间。问题是创建GUI需要一段时间(创建对话、更新表格等)。而且我不能将GUI创建移动到后台线程(如“Task”类),因为我会得到“Not on FXApplication thread”异常。我尝试使用: 以及任务的“调用”方法: 当我在Swing中编写程序时,我可以在EventDispatchThread上显示和更新Splash屏幕,而

  • MinDoc 0.4以上版本支持在Linux和Windows上以服务的方式后台执行,命令如下: 安装服务 ./mindoc_linux_amd64 service install 卸载服务 ./mindoc_linux_amd64 service remove 执行服务安装后,会创建一个以 mindocd 为服务名的服务。 需要以管理员权限运行

  • 我有一个简单的java程序,它只是一段代码,可以从数据库中读取并根据某些条件修改数据库的内容。现在,我想要的是这个程序应该在启动时自动启动并在后台静默运行,除非有人从任务管理器中杀死它。我以前从未做过这样的事情,也不知道具体该怎么做。有人能帮我解决这个问题吗?谢谢你...

  • 问题内容: 我想使用ffmpeg在php中将视频转换为.flv。目前,我正在执行此操作,但是它会挂起浏览器,直到文件上传完毕。我一直在寻找有关如何在后台运行exec()进程的php文档,同时使用返回的PID更新进程。这是我发现的: 我还使用一个技巧来跟踪后台任务是否正在使用返回的PID运行: 我是否想创建一个单独的.php文件,然后从php cli运行以执行以下功能之一?我只需要稍微推动一下即可开

  • 本文向大家介绍Docker 在后台运行容器,包括了Docker 在后台运行容器的使用技巧和注意事项,需要的朋友参考一下 示例 要使容器在后台运行,请-d在容器启动期间提供命令行选项: 该选项-d以分离模式运行容器。它也等效于-d=true。 处于分离模式的容器停止时不能自动删除,这意味着不能将--rm选项与-d选项结合使用。