如何从用户使用 tkinter 决定的日期开始每周安排一次任务?

How to schedule a task once a week from a date decided by the user with tkinter?

我需要每周在用户指定的时间和日期下载一些文件,如 screenshot 所示。 我正在努力整合关于 root.mainloop() 的内部循环。 到目前为止,我已经尝试过 .after 并且有一段时间的结构如下:

def scaricaAuto(myDay, myHour, myMinute):
    while True:
    day = datetime.datetime.now().strftime("%A")
    hour = datetime.datetime.now().strftime("%H")
    minute = datetime.datetime.now().strftime("%M")
    if day == myDay and str(int(hour)) == myHour and str(int(minute)) == myMinute:
       DownloadButton.invoke()
       break
    root.after(60000, scaricaAuto(clickedDays.get(), HourSpin.get(), MinSpin.get()))

仅使用 .after 会导致 Python: maximum recursion depth exceeded while calling a Python object 并且 while 循环无法正常运行,当 if 为真时它会卡在那里并继续调用 DownloadButton。

另外 OS 当按钮功能持续超过几秒时,X 显示我的脚本“无响应”,是否有解决方案?

提前感谢那些花时间阅读我的问题并可能会帮助我的人!

您的代码中有几个问题。首先,您需要删除 while True。那没有用。 Tkinter 已经 运行 通过 mainloop.

进行无限循环

其次,after需要一个函数。您正在调用一个函数并将结果传递给 after.

换句话说,这个:

root.after(60000, scaricaAuto(clickedDays.get(), HourSpin.get(), MinSpin.get()))

... 在功能上与此相同:

result = scaricaAuto(clicedDays.get(), HourSpin.get(), MinSpin.get())
root.after(60000, result)

相反,您需要将 scaricaAuto 作为参数传递,或者您需要创建一个调用您的函数的新函数。对于前者,您可以通过将参数传递给 after.

来将参数传递给函数

例如,

root.after(60000, scaricaAuto, clickedDays.get(), HourSpin.get(), MinSpin.get())

请注意,这会立即调用 .get() 函数,而不是等待整整 60 秒。

更好的解决方案是不向 scaricaAuto 传递任何参数,而是让它在需要值时立即调用 .get() 方法:

def scaricaAuto():
    myDay = clickedDays.get()
    myHour = HourSpin.get()
    myMinute = MinSpin.get()

    now = datetime.datetime.now()
    day = now.strftime("%A")
    hour = now.strftime("%H")
    minute = now.strftime("%M")

    if day == myDay and str(int(hour)) == myHour and str(int(minute)) == myMinute:
       DownloadButton.invoke()
    root.after(60000, scaricaAuto)

只要 GUI 本身是 运行ning,上面的代码就会 运行,假设你在某个时候调用了 mainloop