2017-08-29 20 views
1

基本的には複数のプログレスバーを作成しようとしていますが、各プログレスバーの値は0から100までです。あまりにも奇妙に見える。うまくいけば誰かが私を助けることができます。ありがとう:)Python - Tkinter(ttk)は、独自の値が変更されたプログレスバーを動的に作成します

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

答えて

3

元のコードでは、self.varはロードバーの進行状況を格納する唯一の変数です。 Mainオブジェクトのインスタンスは1つしかないので、self.varのインスタンスが1つしかないため、記述した問題が発生します。

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

注:インスタンス変数とは対照的に、ローカル変数はインスタンス変数の上書きを避けるために、各スレッドのために作成されます。

関連する問題