Python - Tkinter (ttk) 动态创建一个进度条,其自身的值会发生变化
Python - Tkinter (ttk) dynamically create a progressbar with its own value that changes
所以基本上我正在尝试创建多个进度条,每个进度条的值都在 0 到 100 之间。但是现在我的函数也访问其他函数的值,这看起来很奇怪。希望有人能帮助我。谢谢:)
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=self.start_thread)
self.button.pack(fill="y")
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
self.var = tk.IntVar()
self.var.set(0)
self.progessbar = ttk.Progressbar(self.frame, variable=self.var, orient=tk.HORIZONTAL, length=200)
self.progessbar.pack()
self.add_values(self.var)
def add_values(self, var):
self.variable = var
for self.x in range(100):
time.sleep(0.1)
self.variable.set(self.x)
root = tk.Tk()
app = Main(root)
root.mainloop()
在您的原始代码中,self.var 是唯一存储加载栏进度的变量。由于 Main 对象只有一个实例,因此 self.var 只有一个实例,这会导致您描述的问题。为了解决这个问题,我建议为加载栏创建一个单独的 class,如下所示:
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=lambda:self.createBar())
self.button.pack(fill="y")
def createBar(self):
self.t = Thread(target=self.create)
self.t.start()
def create(self):
newBar = LoadingBar(self.master, self.frame)
class LoadingBar(object):
def __init__(self, master, frame):
# Must use same Tkinter frame to add loading bars into
self.master = master
self.frame = frame
self.add_bar()
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
self.var = tk.IntVar()
self.var.set(0)
self.progessbar = ttk.Progressbar(self.frame, variable=self.var, orient=tk.HORIZONTAL, length=200)
self.progessbar.pack()
self.add_values(self.var)
def add_values(self, var):
self.variable = var
for self.x in range(100):
time.sleep(0.1)
self.variable.set(self.x)
root = tk.Tk()
app = Main(root)
root.mainloop()
在单独的线程中创建加载栏的每个实例可以达到预期的效果。
这是另一种方法(没有新的class):
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=self.start_thread)
self.button.pack(fill="y")
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
var = tk.IntVar()
var.set(0)
progessbar = ttk.Progressbar(self.frame, variable=var, orient=tk.HORIZONTAL, length=200)
progessbar.pack()
self.add_values(var)
def add_values(self, var):
variable = var
for x in range(100):
time.sleep(0.1)
variable.set(x)
root = tk.Tk()
app = Main(root)
root.mainloop()
注意:局部变量是为每个线程创建的,而不是实例变量,以避免实例变量被覆盖。
所以基本上我正在尝试创建多个进度条,每个进度条的值都在 0 到 100 之间。但是现在我的函数也访问其他函数的值,这看起来很奇怪。希望有人能帮助我。谢谢:)
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=self.start_thread)
self.button.pack(fill="y")
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
self.var = tk.IntVar()
self.var.set(0)
self.progessbar = ttk.Progressbar(self.frame, variable=self.var, orient=tk.HORIZONTAL, length=200)
self.progessbar.pack()
self.add_values(self.var)
def add_values(self, var):
self.variable = var
for self.x in range(100):
time.sleep(0.1)
self.variable.set(self.x)
root = tk.Tk()
app = Main(root)
root.mainloop()
在您的原始代码中,self.var 是唯一存储加载栏进度的变量。由于 Main 对象只有一个实例,因此 self.var 只有一个实例,这会导致您描述的问题。为了解决这个问题,我建议为加载栏创建一个单独的 class,如下所示:
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=lambda:self.createBar())
self.button.pack(fill="y")
def createBar(self):
self.t = Thread(target=self.create)
self.t.start()
def create(self):
newBar = LoadingBar(self.master, self.frame)
class LoadingBar(object):
def __init__(self, master, frame):
# Must use same Tkinter frame to add loading bars into
self.master = master
self.frame = frame
self.add_bar()
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
self.var = tk.IntVar()
self.var.set(0)
self.progessbar = ttk.Progressbar(self.frame, variable=self.var, orient=tk.HORIZONTAL, length=200)
self.progessbar.pack()
self.add_values(self.var)
def add_values(self, var):
self.variable = var
for self.x in range(100):
time.sleep(0.1)
self.variable.set(self.x)
root = tk.Tk()
app = Main(root)
root.mainloop()
在单独的线程中创建加载栏的每个实例可以达到预期的效果。
这是另一种方法(没有新的class):
# -*- coding: utf-8 -*-
import tkinter.ttk as ttk
import tkinter as tk
from threading import Thread
import time
class Main(object):
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master, width=400, height=400)
self.frame.pack(expand=True)
self.button = tk.Button(self.frame, text="Add Bar", command=self.start_thread)
self.button.pack(fill="y")
def start_thread(self):
self.t = Thread(target=self.add_bar)
self.t.start()
def add_bar(self):
var = tk.IntVar()
var.set(0)
progessbar = ttk.Progressbar(self.frame, variable=var, orient=tk.HORIZONTAL, length=200)
progessbar.pack()
self.add_values(var)
def add_values(self, var):
variable = var
for x in range(100):
time.sleep(0.1)
variable.set(x)
root = tk.Tk()
app = Main(root)
root.mainloop()
注意:局部变量是为每个线程创建的,而不是实例变量,以避免实例变量被覆盖。