2011-08-02 11 views
3

アップロードの実行状況をトレースするFTP機能がありますが、スレッディングの理解には限界があり、解決策を実装できませんでした... GUIの進捗状況を追加したいスレッドを使用して、現在のアプリケーションにバーを追加します。他のスレッドから更新できる非同期スレッドを使用して、基本的な機能を誰かに教えてもらえますか?GUIの進捗状況にスレッディングを追加するのに役立つ

def ftpUploader(): 
    BLOCKSIZE = 57344 # size 56 kB 

    ftp = ftplib.FTP() 
    ftp.connect(host) 
    ftp.login(login, passwd) 
    ftp.voidcmd("TYPE I") 
    f = open(zipname, 'rb') 
    datasock, esize = ftp.ntransfercmd(
     'STOR %s' % os.path.basename(zipname)) 
    size = os.stat(zipname)[6] 
    bytes_so_far = 0 
    print 'started' 
    while 1: 
     buf = f.read(BLOCKSIZE) 
     if not buf: 
      break 
     datasock.sendall(buf) 
     bytes_so_far += len(buf) 
     print "\rSent %d of %d bytes %.1f%%\r" % (
       bytes_so_far, size, 100 * bytes_so_far/size) 
     sys.stdout.flush() 

    datasock.close() 
    f.close() 
    ftp.voidresp() 
    ftp.quit() 
    print 'Complete...' 
+1

は、新しいスレッドからGUIを使用しないでください。 1つのスレッドに対してすべてのGUI操作を予約し、2番目のスレッドにFTPを実行させます。 –

答えて

1

はここで念のために、スレッドの概要です:)私はあなたがwxWidgetsのをチェックアウトする必要があることを言うこと以外に、GUIのものにあまり詳細には触れません。あなたのような長い時間を要する何か、やるたび:

from time import sleep 
for i in range(5): 
    sleep(10) 

をあなたは、ユーザーに、コードのブロック全体が50秒かかるように見えることに気づくでしょう。その5秒間に、あなたのアプリケーションはインターフェースを更新するようなことはできないので、凍っているように見えます。この問題を解決するために、スレッド化を使用します。

通常、この問題には2つの部分があります。あなたが処理したいものの全体的なセット、そしてしばらく時間がかかる操作を、私たちは切り詰めたいと思っています。この場合、全体のセットはforループであり、私たちが切ってほしい動作はsleep(10)関数です。

これまでの例に基づいて、スレッドコード用のクイックテンプレートがあります。あなたは、この例にあなたのコードを作業することができるはずです。

from threading import Thread 
from time import sleep 

# Threading. 
# The amount of seconds to wait before checking for an unpause condition. 
# Sleeping is necessary because if we don't, we'll block the os and make the 
# program look like it's frozen. 
PAUSE_SLEEP = 5 

# The number of iterations we want. 
TOTAL_ITERATIONS = 5 

class myThread(Thread): 
    ''' 
    A thread used to do some stuff. 
    ''' 
    def __init__(self, gui, otherStuff): 
     ''' 
     Constructor. We pass in a reference to the GUI object we want 
     to update here, as well as any other variables we want this 
     thread to be aware of. 
     ''' 
     # Construct the parent instance. 
     Thread.__init__(self) 

     # Store the gui, so that we can update it later. 
     self.gui = gui 

     # Store any other variables we want this thread to have access to. 
     self.myStuff = otherStuff 

     # Tracks the paused and stopped states of the thread. 
     self.isPaused = False 
     self.isStopped = False 

    def pause(self): 
     ''' 
     Called to pause the thread. 
     ''' 
     self.isPaused = True 

    def unpause(self): 
     ''' 
     Called to unpause the thread. 
     ''' 
     self.isPaused = False 

    def stop(self): 
     ''' 
     Called to stop the thread. 
     ''' 
     self.isStopped = True 

    def run(self): 
     ''' 
     The main thread code. 
     ''' 
     # The current iteration. 
     currentIteration = 0 

     # Keep going if the job is active. 
     while self.isStopped == False: 
      try: 
       # Check for a pause. 
       if self.isPaused: 
        # Sleep to let the os schedule other tasks. 
        sleep(PAUSE_SLEEP) 
        # Continue with the loop. 
        continue 

       # Check to see if we're still processing the set of 
       # things we want to do. 
       if currentIteration < TOTAL_ITERATIONS: 
        # Do the individual thing we want to do. 
        sleep(10) 
        # Update the count. 
        currentIteration += 1 
        # Update the gui. 
        self.gui.update(currentIteration,TOTAL_ITERATIONS) 
       else: 
        # Stop the loop. 
        self.isStopped = True 

      except Exception as exception: 
       # If anything bad happens, report the error. It won't 
       # get written to stderr. 
       print exception 
       # Stop the loop. 
       self.isStopped = True 

     # Tell the gui we're done. 
     self.gui.stop() 

このスレッドを呼び出すために、あなたがしなければならないすべては、次のとおりです。

aThread = myThread(myGui,myOtherStuff) 
aThread.start() 
+0

提供された例を使用してコードを挿入して実行できましたが、メインウィンドウを更新する方法がまだわかりません...元のGUIインスタンスにステータスを戻す方法はありますか? BTY:wxPythonを使用しているIm。 – Simpleton

+0

スレッドを構築するときに、そのウィンドウをパラメータとしてスレッドに渡し、ウィンドウをローカルに格納します。それはself.guiだ。それが終わったら、メインスレッドのメソッドを呼び出して更新することができます。 –

関連する問題