【问题标题】:Python - Tkinter (ttk) dynamically create a progressbar with its own value that changesPython - Tkinter (ttk) 动态创建一个进度条,其值会发生变化
【发布时间】:2017-08-29 20:28:28
【问题描述】:

所以基本上我正在尝试制作多个进度条,每个进度条的值从 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()

【问题讨论】:

    标签: python python-3.x tkinter ttk


    【解决方案1】:

    在您的原始代码中,self.var 是唯一存储加载栏进度的变量。由于 Main 对象只有一个实例,因此 self.var 只有一个实例,这会导致您描述的问题。为了解决这个问题,我建议为加载栏创建一个单独的类,如下所示:

    # -*- 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()
    

    在单独的线程中创建加载栏的每个实例可以获得所需的效果。

    这是另一种方法(没有新类):

    # -*- 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()
    

    注意:为每个线程创建局部变量,而不是实例变量,以避免覆盖实例变量。

    【讨论】:

      猜你喜欢
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多