tkinter GUI由于after()调用中的一个函数而出现滞后。

huangapple go评论58阅读模式
英文:

tkinter GUI lagging due to a function in after() call

问题

我目前正在尝试更新我的tkinter GUI上标签的文本,我从一个单独的函数中获取更新标签文本,该函数调用API并检索数据。然而,我注意到尽管标签的文本通过after()成功更新,但GUI变得非常迟钝和无响应,在我拖动它穿过屏幕后需要3-4秒才能移动。以下是我代码中相关的部分。我已经修改了它以在单独的线程上运行tkinter,但我对此不太确定,因为我对多线程不太熟悉。我会感激任何建议。

class App(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()

    def callback(self):
        self.root.quit()

    def update_top_coin_list(self, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
        usdt_krw = get_usdt_krw_yfinance()
        for (coin_button, coin_kimchi_enter, coin_kimchi_exit) in zip(update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
            coin_kimchi_enter['text'], coin_kimchi_exit['text'] = get_info_single_coin(coin_button['text'], usdt_krw, 'Binance')
        self.root.after(1000, self.update_top_coin_list, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list)

    def run(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.callback)

        self.root.geometry("900x225")
        self.root.resizable(0, 0)

        # 在此省略了与问题不太相关的框架/小部件等的代码

        # 第一次运行
        self.update_top_coin_list(coin_button_list, coin_kimchi_enter_list, coin_kimchi_exit_list)

        self.root.mainloop()

如您所见,get_info_single_coin函数在update_top_coin_list内部调用,每隔1秒运行一次。这些列表本身非常短(5个值),因此这不是问题,但是get_info_single_coin函数调用API并检索数据。我认为这导致GUI变得迟钝。是否有解决方法?

英文:

I'm currently trying to update the labels' texts on my tkinter GUI where I get the update label texts from a separate function that calls to APIs and retrieves data. However, I have noticed that while the labels' texts are successfully updating through after(), the GUI becomes very sluggish and unresponsive, taking 3-4 seconds for the window to move after I drag it across the screen. Here are parts of my code below that are relevant. I have modified it to run tkinter on a separate thread, but I'm not too sure about it as I'm new to multi-threading. I would appreciate any advice.

class App(threading.Thread,):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()

    def callback(self):
        self.root.quit()

    def update_top_coin_list(self, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
        usdt_krw = get_usdt_krw_yfinance()
        for (coin_button, coin_kimchi_enter, coin_kimchi_exit) in zip(update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
            coin_kimchi_enter['text'], coin_kimchi_exit['text'] = get_info_single_coin(coin_button['text'], usdt_krw, 'Binance')
        self.root.after(1000, self.update_top_coin_list, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list)

    def run(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.callback)

        self.root.geometry("900x225")
        self.root.resizable(0, 0)

        # Redacted code here for frames/widgets/etc not super relevant to the issue

        # Run first time
        self.update_top_coin_list(coin_button_list, coin_kimchi_enter_list, coin_kimchi_exit_list)

        self.root.mainloop()

Ask you can see, the function get_info_single_coin is called within the update_top_coin_list which is run every 1 second. The lists themselves are very short (5 values) so that's not the issue but the function get_info_single_coin calls to APIs and retrieves data. I'm thinking that's causing the GUI to become sluggish. Is there any solution to this?

答案1

得分: 1

get_info_single_coin函数从API获取数据,网络请求可能会消耗时间,在GUI内可能导致无响应。

让我们将这些API调用放入单独的线程中。

def update_top_coin_list(self, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
    def thread_update(coin_button, coin_kimchi_enter, coin_kimchi_exit):
        usdt_krw = get_usdt_krw_yfinance()
        coin_kimchi_enter['text'], coin_kimchi_exit['text'] = get_info_single_coin(coin_button['text'], usdt_krw, 'Binance')
        self.root.after(1000, self.update_top_coin_list, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list)

    for coin_button, coin_kimchi_enter, coin_kimchi_exit in zip(update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
        threading.Thread(target=thread_update, args=(coin_button, coin_kimchi_enter, coin_kimchi_exit)).start()

希望这对你有所帮助。

英文:

The function get_info_single_coin, retrieves data from APIs, network requests can be time-consuming, and inside a GUI that is what may cause the unresponsiveness.

Lets do those API call into separate threads.

def update_top_coin_list(self, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
    def thread_update(coin_button, coin_kimchi_enter, coin_kimchi_exit):
        usdt_krw = get_usdt_krw_yfinance()
        coin_kimchi_enter['text'], coin_kimchi_exit['text'] = get_info_single_coin(coin_button['text'], usdt_krw, 'Binance')
        self.root.after(1000, self.update_top_coin_list, update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list)

    for coin_button, coin_kimchi_enter, coin_kimchi_exit in zip(update_ticker_label_list, update_kimp_enter_label_list, update_kimp_exit_label_list):
        threading.Thread(target=thread_update, args=(coin_button, coin_kimchi_enter, coin_kimchi_exit)).start()

huangapple
  • 本文由 发表于 2023年6月1日 15:53:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定