【发布时间】: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