2017-08-29 4 views
1

Donc, fondamentalement, j'essaie de faire plusieurs progressbar et chaque valeur progressbars va de 0 à 100. Mais maintenant mes fonctions accèdent aux valeurs des autres aussi et ça a l'air bizarre. J'espère que quelqu'un peut m'aider. Merci :)Python - Tkinter (ttk) crée dynamiquement une barre de progression avec sa propre valeur qui change

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

Répondre

3

Dans votre code d'origine, self.var est la seule variable qui stocke la progression de la barre de chargement. Comme il n'y a qu'une seule instance de l'objet principal, il n'y a qu'une seule instance de self.var qui entraîne le problème que vous avez décrit. Pour résoudre ce problème, je recommande la création d'une catégorie distincte pour la barre de chargement comme indiqué ci-dessous:

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

Création chaque instance de la barre de chargement dans un thread séparé permet l'effet désiré.

Voici une autre approche (pas nouvelle classe):

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

Remarque: Les variables locales sont créées pour chaque thread par opposition aux variables d'instance pour éviter l'écrasement des variables d'instance.