【问题标题】:tkinter progressbar not updating in timetkinter 进度条未及时更新
【发布时间】:2021-07-11 08:01:24
【问题描述】:

我制作了一个调用某些函数的脚本。在每个函数之后我想更新我的进度条。这是我的进度条代码:


class loading(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        s = ttk.Style()
        s.theme_use('clam')
        s.configure("red.Horizontal.TProgressbar", foreground='red', background='red')

        self.progress = ttk.Progressbar(self, style="red.Horizontal.TProgressbar", orient='horizontal',
                                   length=101, mode='determinate')
        self.progress.pack(pady=10)

    def updateprogress(self):
        self.progress.step(20)
        return

但是当我尝试在我的脚本函数之后调用更新进度时,它直到最后才更新。所以在我所有的功能完成后,进度条会从 0 变为 100 而不是步数。

        loading.updateprogress()
        script.install_requerement()
        loading.updateprogress()
        script.clone_vuestore_front()
        loading.updateprogress()

我该如何解决这个问题?

编辑: 我试图在我的代码中使用线程。这次我会发布整个脚本:

#!/usr/bin/python
import subprocess
import os
from threading import Thread
from tkinter import ttk
import tkinter as tk
import time


class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.wm_geometry('700x400')
        self.title('Install and integrate Vue Storefront')
        self._frame = None
        self.switch_frame(first_page)

    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()
        return self._frame



class loading(tk.Frame):
    number=10
    def __init__(self, master):
        tk.Frame.__init__(self, master)

    def t_create_progress_bar(self):
        progress_bar = ttk.Progressbar(self, orient="horizontal", length=400)
        progress_bar.pack()

        progress_bar.after(1, self.t_loop_progress_bar, progress_bar)

        self.mainloop()

    def t_loop_progress_bar(self, progress_bar):
        progress_bar["value"] = self.number
        # Update it again in 100ms
        progress_bar.after(100, self.t_loop_progress_bar, progress_bar)


class first_page(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        t = tk.Message(self, width=500,
                       text='first page')
        t.pack()
        tk.Button(self, text='Accept', command=lambda: \
            self.AcceptClick(master)).pack(side=tk.RIGHT,
                                           padx=5, pady=5)

    def AcceptClick(self, master):
        loadingclass =  master.switch_frame(loading)
        thread = Thread(target=loadingclass.t_create_progress_bar(), daemon=True)
        thread.start()

        loadingclass.number = 0  # 0% done
        subprocess.run('sudo apt-get update', shell=True)
        loadingclass.number = 25  # 25% done
        subprocess.run('apt install nodejs', shell=True)
        loadingclass.number = 50  # 50% done
        subprocess.run('sudo apt-get update', shell=True)
        loadingclass.number = 75  # 75% done


if __name__ == '__main__':
    app = Application()
    app.mainloop()

框架确实切换了,我看到了进度条。但是现在脚本在我关闭窗口后运行子进程,而不是我想运行一个函数,然后更新进度条。

我做错了什么?

【问题讨论】:

  • 为什么你有progress作为一个全局变量?这不是你应该在 python 中使用类的方式。
  • 整个全局和静态方法没有任何意义
  • this
  • 我希望能够从任何地方调用 updateprogress()。这就是为什么它是一个静态方法。你建议我应该怎么做?
  • @amjada 我建议你看一个 OOP 教程。你可以把progress = ttk.Progressbar(...)改成self.progress = ttk.Progressbar(...)progress.pack(...)改成self.progress.pack(...),去掉@staticmethod,把def updateprogress()改成def updateprogress(self)progress.step(30)改成self.progress.step(30)

标签: python tkinter progress-bar


【解决方案1】:

正如@TheLizzard 建议的那样,尝试将所有局部变量更改为静态自变量。当您更新进度条值时(在self.progressbar.step(...) 之后),也尝试调用root.update()。因为据我所知root.mainloop() 是同步的,这就是为什么如果您在同步代码之后调用它,进度条只会在此之后更新,如果您之前调用它 - 它只会停止下面的代码。

【讨论】:

  • 如果进程运行时间足够长,它仍然会挂起窗口。
  • @TheLizzard,首先,问题的作者没有告诉任何脚本的时间,其次,如果你不调用root.mainloop,tk不会更新帧,阿法克
  • 这就是为什么你应该在另一个线程中运行 GUI。看看 cmets(关于问题)。我链接了一些非常相似的东西,它在另一个线程中运行 GUI,并且可以执行任何进程而不会使窗口无响应。
  • @TheLizzard,我根本不喜欢 tk,所以我在我的项目中使用 flaskwebgui 或 PyQt。所以,很久以前用的时候,我用线程来分离我的代码和tk更新,效果很好
  • 线程和 tkinter 不是一个好主意。 Tkinter 有时会崩溃。
猜你喜欢
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
相关资源
最近更新 更多