在 tkinter 循环中刷新数据
refreshing data inside tkinter loop
情况:我有一个 tkinter GUI 显示从 API 收集的天气数据。我有一个 'get_weather' 函数,它从 API 请求数据。响应通过管道传输到 'formatting' 函数,然后返回到 'get_weather' 函数。然后将格式化的字符串显示为 tkinter 标签的文本。该程序旨在 运行 在启动时 (cronjob) 并持续保持 运行ning。一切都很好,除了...
问题:我无法让'get_weather'功能自动刷新。我希望 'get_weather' 函数每 30 分钟 运行 将数据从 API 更新到 GUI。
我试过: 无限循环;这会阻止 Tk 循环启动。在代码中放入 time.sleep(60);停止 GUI 启动一分钟。和 after 方法(用法见下文)。它似乎没有做任何事情,除非我将时间参数设置为一个巨大的数字。然后它延迟了 GUI 启动。
旁注: 我没有自己制作 class。这是下一次迭代的计划。我只是没有信心做出 classes。我想在我这样做之前解决其他问题。此外,我在 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()
我可以 post 完整代码我只是认为没有人愿意通读 300 行来获得一个简单的解决方案。
编辑:更正了按钮命名错误
+ 添加 'change_location' 函数到 summery
也把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 方法抽象为另一个函数 'refresher'。 'refresher' 调用 'get_weather' 但 after 方法循环 'refresher' 而不是 'get_weather'。 'refresher' 在 Tk 循环中被调用。
使用 'change_location' 函数仍然会复合计时器(通过调用 'get_weather')。因为 after 方法附加到不同的函数,所以它只会将计时器复合一个周期。计时器不太可能复合到足以减慢程序速度并在下一个周期中以任何一种方式进行更正。
def refresher():
get_weather()
root.after(1800000, refresher)
情况:我有一个 tkinter GUI 显示从 API 收集的天气数据。我有一个 'get_weather' 函数,它从 API 请求数据。响应通过管道传输到 'formatting' 函数,然后返回到 'get_weather' 函数。然后将格式化的字符串显示为 tkinter 标签的文本。该程序旨在 运行 在启动时 (cronjob) 并持续保持 运行ning。一切都很好,除了...
问题:我无法让'get_weather'功能自动刷新。我希望 'get_weather' 函数每 30 分钟 运行 将数据从 API 更新到 GUI。
我试过: 无限循环;这会阻止 Tk 循环启动。在代码中放入 time.sleep(60);停止 GUI 启动一分钟。和 after 方法(用法见下文)。它似乎没有做任何事情,除非我将时间参数设置为一个巨大的数字。然后它延迟了 GUI 启动。
旁注: 我没有自己制作 class。这是下一次迭代的计划。我只是没有信心做出 classes。我想在我这样做之前解决其他问题。此外,我在 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()
我可以 post 完整代码我只是认为没有人愿意通读 300 行来获得一个简单的解决方案。
编辑:更正了按钮命名错误 + 添加 'change_location' 函数到 summery
也把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 方法抽象为另一个函数 'refresher'。 'refresher' 调用 'get_weather' 但 after 方法循环 'refresher' 而不是 'get_weather'。 'refresher' 在 Tk 循环中被调用。
使用 'change_location' 函数仍然会复合计时器(通过调用 'get_weather')。因为 after 方法附加到不同的函数,所以它只会将计时器复合一个周期。计时器不太可能复合到足以减慢程序速度并在下一个周期中以任何一种方式进行更正。
def refresher():
get_weather()
root.after(1800000, refresher)