刷新tkinter循环内的数据



情况:我有一个tkinter GUI,显示从API收集的天气数据。我有一个"get_weather"函数,它从API请求数据。响应通过管道传输到"格式化"函数,然后返回到"get_weather"函数。然后,一个格式化的字符串显示为tkinter标签的文本。该程序旨在在启动时运行(cronjob)并保持连续运行。一切都很好,除了。。。

问题:我无法使"get_weather"函数自动刷新。我希望"get_weather"函数每30分钟运行一次,以将数据从API更新到GUI。

我尝试过:一个无限的While循环;这阻止了Tk循环的启动。在代码中放入time.sleep(60);停止GUI启动一分钟。以及后一种方法(用法见下文)。除非我把时间参数设为一个巨大的数字,否则它似乎什么都没做。然后它推迟了GUI的启动。

附带说明:我没有自己上课。这就是下一次迭代的计划。我只是对上课没信心。在我这么做之前,我想先解决其他问题。此外,我还拥有Tk循环开始时定义的所有函数。它们在循环中被调用。这对我来说很有道理,但如果有人有理由参与循环,我想听听。我已经学会了线程,但我不认为这是解决方案。

代码看起来像:(程序有300行,还有其他功能。我只想总结一下问题代码)

from Tkinter import Tk*
import [a few other modules]
def change_location(city):
# passes a 'city' value from an Entry widget
# sends request to a geo location api for gps coordinates.
# saves location coordinates to a local config file.
getweather()
def formatting(json):
# takes json from api and formats it to a string
return string
def get_weather():
# opens a local config file with gps coordinates.
# Note: the weather api I'm using requires gps coordinates
# uses gps coordinates in weather api request
weather['text'] = formatting(response.json())
# start of tkinter loop
root = Tk()
weather = Label(root)
# manual refresh button that works
refresh = Button(root, text="Refresh", command=get_weather)
new_city = Entry(root)
weather.grid(row=0, column=0)
refresh.grid(row=0, column=1)
new_city.grid(row2, column=1)
# after method like his only seems to delay GUI launch only calls 'get_weather' once. 
# I also tried weather.after(10000, get_weather())
root.after(10000, get_weather)
root.mainloop()

我可以发布完整的代码,我只是觉得没有人想通读300行来获得一个简单的解决方案。

编辑:更正按钮命名拼写错误+在summery 中添加了"change_location"函数

也将root.after(1800000, get_weather)放入get_weather()中,因此:

def get_weather():
root.after(1800000, get_weather) # 30 mins is 1800000 ms

所以现在,一旦函数最初被调用,它将每30分钟被调用一次。

尽管注意,button可能是打字错误,但您忘记将其放入Button()中。无论如何,如果你按下button,那么这个after()将被调用两次,从而加快了进程。因此,建议使用标志来确保只按下一次按钮,然后禁用该按钮。或者另辟蹊径。我建议你不要使用任何按钮。

我找到了一个变通办法。这不是一个防故障的解决方案,但效果很好。我将after方法抽象为另一个函数"refresh"refresher调用"get_weather",但after方法循环"refresher"而不是"get_wather"在Tk循环中调用refresher。

使用"change_location"函数仍然会合成计时器(通过调用"get_weather")。由于after方法附加了一个不同的函数,它只将计时器组合为一个循环。无论哪种方式,计时器都不太可能被复合到足以减慢程序速度并在下一个周期中进行校正。

def refresher():
get_weather()
root.after(1800000, refresher)

最新更新