window 在不使用按钮的情况下打开时如何启动线程以更新 tkinter 中的网络数据

How to start a thread to update network data in tkinter when window opens without using a button

以下代码使用从 Binance public API 下载的 BTCUSDT 价格更新标签。该线程是通过一个按钮启动的,但是当 window 打开时,我不知道如何在没有按钮的情况下启动它。

from tkinter import *
import time
import requests      
import threading

def get_price():
    while True:
        root_url = 'https://api.binance.com/api/v3/avgPrice'
        symbol = 'BTCUSDT'
        url = root_url + '?symbol=' + symbol
        data = requests.get(url).json()
        my_label.config(text=data['price'])
        time.sleep(60)
        

root = Tk()
root.geometry('400x200')

my_label = Label(root, text='Hello There')
my_label.pack(pady=20)

my_button = Button(root, text='Start', command=lambda:threading.Thread(target=get_price).start())
my_button.pack(pady=20)

root.mainloop()

我建议将主线程与执行

的线程分离

使用库队列读取数据,你可以轻松完成的事情

面向对象的方法。

我把时间调到了 3 秒,问候。

#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import threading
import queue
import time
import requests  


class MyTrhead(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.queue = queue.Queue()
        self.check = True

    def stop(self):
        self.check = False

    def run(self):

        """Feeds the tail."""

        while self.check:
            root_url = 'https://api.binance.com/api/v3/avgPrice'
            symbol = 'BTCUSDT'
            url = root_url + '?symbol=' + symbol
            data = requests.get(url).json()
            msg = data['price']
            print("on run: {0}".format(msg))
            time.sleep(3)
            self.queue.put(msg)
    
    def check_queue(self, obj):

        """Returns a formatted string"""

        while self.queue.qsize():
            try:
                x = self.queue.get(0)
                msg = "{0}".format(x)
                print("check_queue {0}".format(msg))
                obj.set(msg)
            except queue.Empty:
                pass
            

class App(tk.Tk):
    """Application start here"""
    def __init__(self):
        super().__init__()

        self.title("Simple App")

        self.protocol("WM_DELETE_WINDOW", self.on_close)

        self.data = tk.StringVar()

        self.data.set("Hello World")

        self.init_ui()

        self.on_start()
       
    def init_ui(self):

        f0 = ttk.Frame(self)

        self.my_label = ttk.Label(f0, textvariable=self.data)
        self.my_label.pack()
        
        f0.pack(fill=tk.BOTH, expand=1)

    def on_start(self):

          self.my_thread = MyTrhead()
          self.my_thread.start()
          self.periodic_call()        
        
    def periodic_call(self):

        self.my_thread.check_queue(self.data)

        if self.my_thread.is_alive():
            self.after(1, self.periodic_call)
        else:
            pass
                
    def on_close(self, evt=None):

        msg = "Do you want to quit?"
        if messagebox.askokcancel(self.title(), msg, parent=self):
            if self.my_thread is not None:
                self.my_thread.stop()

            self.destroy()

def main():
    app = App()
    app.mainloop()

if __name__ == '__main__':
    main()