【问题标题】:Display Tkinter GUI While A Loop is Running在循环运行时显示 Tkinter GUI
【发布时间】:2019-05-01 07:54:44
【问题描述】:

基本上,我正在编写 Python 中订阅者计数器应用程序的“草稿”。我使用 YouTube Data 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()

【问题讨论】:

标签: python api tkinter while-loop


【解决方案1】:

线程可以解决您遇到的问题,但 tkinter after()this answer explains it well 包含一个更简单的解决方案:

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多