循环运行时显示Tkinter GUI



本质上,我正在python中编写一个订阅者计数器应用程序的"草稿"。我使用YouTube数据API从YouTube获取数据,然后循环这段代码来更新订阅人数。但是,由于我的GUI的代码在循环之后,它永远不会开始,因为循环是无限的,永远不会结束。我尝试将GUI部分放在代码之前以获取子计数,但没有定义任何变量,因此返回错误。因此,基本上我的问题是如何重新组织它,使其工作,并在GUI中更新子计数。我听说有人使用线程模块,但我对此没有太多经验。

import urllib.request
import json
from tkinter import*
name ="pewdiepie"
key = "AIzaSyDAOUFomRB1lxdb_fvSKKaG-FSZDRoVt_s"

i = 1
while i<99999999:
data = urllib.request.urlopen("https://www.googleapis.com/youtube/v3/channels?part=statistics&forUsername="+name+"&key="+key).read()
subs = json.loads(data)["items"][0]["statistics"]["subscriberCount"]
subc =("{:,d}".format(int(subs)))
print(subc)
i = i + 1

root = Tk()
root.geometry("900x600")
root.title("Sub Counter")
label1 = Label(text="Sub Count:", font=("Comic Sans MS", 45), fg="Brown").place(x=10, y=20)
label2 = Label(text=subc, font=("Comic Sans MS", 45), fg="Red").place(x=10, y=130)
root.mainloop()

线程可以解决您遇到的问题,但tkinterafter()中包含了一个更简单的解决方案,这个答案很好地解释了这一点:

after(delay_ms,callback=None,*args(

注册在给定时间后调用的报警回调。

这允许您在定义的一段时间后调用函数。因此,使用它,我们可以将while循环更改为一个函数,将需要更新的小部件交给该函数,并在函数末尾添加另一个after()以继续循环:

def func(label2):
data = urllib.request.urlopen("https://www.googleapis.com/youtube/v3/channels?part=statistics&forUsername="+name+"&key="+key).read()
subs = json.loads(data)["items"][0]["statistics"]["subscriberCount"]
subc =("{:,d}".format(int(subs)))
label2.config(text=subc)
label2.update()
root.after(10, lambda:func(label2))

然后我们需要一个起点:

func(label2)

在您的程序中进行一些其他更改后,我们最终得出以下结果:

import urllib.request
import json
from tkinter import*
name ="pewdiepie"
key = "AIzaSyDAOUFomRB1lxdb_fvSKKaG-FSZDRoVt_s"

def func(label2):
data = urllib.request.urlopen("https://www.googleapis.com/youtube/v3/channels?part=statistics&forUsername="+name+"&key="+key).read()
subs = json.loads(data)["items"][0]["statistics"]["subscriberCount"]
subc =("{:,d}".format(int(subs)))
label2.config(text=subc)
label2.update()
root.after(10, lambda:func(label2))

root = Tk()
root.geometry("900x600")
root.title("Sub Counter")
label1 = Label(text="Sub Count:", font=("Comic Sans MS", 45), fg="Brown")
label2 = Label(font=("Comic Sans MS", 45), fg="Red")
label1.place(x=10, y=20)
label2.place(x=10, y=130)
func(label2)
root.mainloop()

附带说明一下,您可以通过使用OOP:来进一步优化

import urllib.request
import json
from tkinter import*
class App():
def __init__(self, root):
self.root = root
self.name = "pewdiepie"
self.key = "AIzaSyDAOUFomRB1lxdb_fvSKKaG-FSZDRoVt_s"
self.root.geometry("900x600")
self.root.title("Sub Counter")
self.label1 = Label(text="Sub Count:", font=("Comic Sans MS", 45), fg="Brown")
self.label2 = Label(font=("Comic Sans MS", 45), fg="Red")
self.label1.place(x=10, y=20)
self.label2.place(x=10, y=130)
self.root.after(0, self.func)
def func(self, *args):
self.data = urllib.request.urlopen("https://www.googleapis.com/youtube/v3/channels?part=statistics&forUsername="+self.name+"&key="+self.key).read()
self.subs = json.loads(self.data)["items"][0]["statistics"]["subscriberCount"]
self.subc =("{:,d}".format(int(self.subs)))
self.label2.config(text=self.subc)
self.label2.update()
root.after(10, self.func)
root = Tk()
App(root)
root.mainloop()

最新更新