0

現在、Python 2.7 用の Tkinter GUI を作成していますが、プログレス バーの操作に問題があります。時間がかかる大きなファイルをプログラムにロードする必要があるため、ファイルのロード中にプログラムがフリーズしていないことをユーザーに示す進行状況バーを表示したいと考えました。残念ながら、ファイルの読み込み中に進行状況バーが更新されないようです:(進行状況バー用の新しいスレッドを作成しようとしましたが、うまくいきませんでした。重い関数呼び出し?

私のコードの関連部分は次のようになります。

import Tkinter as tk
import ttk as ttk
import pandas as pd
import tkFileDialog as tfgiag

self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])
self.t = threading.Thread(target = self.pb.start)
self.t.start()  
#read in each CSV file selected by the user
for myfile in root.tk.splitlist(mynewdata): 
    foo = pd.read_csv(myfile)    
    self.data.appendMainData(foo)
self.pb.stop()
4

2 に答える 2

0

self.frame.update_idletasks()すべてのステートメントの後に使用しますself.pb.step(x)。ここで、「x」はプログレスバーの値が増加する値を表します

于 2013-09-25T04:35:54.150 に答える
0

Python の「スレッド」は、GIL (グローバル インタープリター ロック) と呼ばれるものによって、すべてが順次ロックされています。これは基本的に、同じ python プロセスから生成されたスレッドが、必要なように並行して実行されないことを意味します。代わりに、それらはすべてメインの Python プロセスで時間を争っています。

あなたの場合、1回のプロセスで監視しようとしている集中的なプロセスがある場合、おそらくGILを占有し、スレッドに解放していません。

1 つのオプション: readline メソッドを使用してみてください。これにより、進行状況バーの更新行を挿入するのに十分なファイル入力作業が分割されます。

openfile = open(filename, 'r')
for eachline in openfile.readlines():
    append_line(eachline)
    update_progressBar()

より簡単な別のオプションは、python のmultiprocessingモジュールを使用して csv の開始を別のプロセスにオフロードすることです。これは、おそらく慣れ親しんでいるスレッドをエミュレートします。csv を読み取り、その行をキューに追加する新しいプロセスを開始します。完了したら、完了を知らせるセンチネル値をキューに追加して、メイン プロセスがプログレス バーの更新を停止し、生成されたプロセスに参加するタイミングを認識できるようにします。何かのようなもの:

import Tkinter as tk
import ttk as ttk
import pandas as pd
import tkFileDialog as tfgiag
from multiprocessing import Process, Queue

self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])

csvqueue=Queue(1) #A mp-enabled queue with one slot to results.
#read in each CSV file selected by the user
offloadedProcess=Process(target=csvread, args=(filename, outputqueue))
offloadedProcess.start()
procNotDone=False
while procNotDone:
    result = getNewResultFromQueue(outputqueue) #pesudo code
    update_ProgressBar() #<--- this should get hit more often now
    if result.isLastValue:
        offloadedProcess.join() #Join the process, since its now done
    else:
        csvresults.append(result)


def csvreadOffload(filename, outputqueue):
    for myfile in root.tk.splitlist(mynewdata): 
        foo = pd.read_csv(myfile)    
        if foo is not END:#Pesudo code here
            outputqueue.append(foo)
        else:
            outputqueue.append('Empty results')#pseudo code
于 2013-09-19T16:19:45.357 に答える