2

wx.ProgressDialogを使用して、メソッドが呼び出された時間を計るにはどうすればよいimgSearchですか? このimgSearchメソッドは、ユーザーの PC で画像ファイルを見つけます。wx.ProgressDialog実行中に実行して、実行にかかるimgSearch時間を表示するにはどうすればよいimgSearchですか?

これが私のコードです:

def onFind (self,event)# triggered by a button click
    max = 80
    dlg = wx.ProgressDialog("Progress dialog example","An informative message",parent=self, style = wx.PD_CAN_ABORT| wx.PD_APP_MODAL| wx.PD_ELAPSED_TIME| wx.PD_REMAINING_TIME)

    keepGoing = True
    count = 0
    imageExtentions = ['*.jpg', '*.jpeg', '*.png', '*.tif', '*.tiff']
    selectedDir = 'C:\\'
    imgSearch.findImages(imageExtentions, selectedDir)# my method

    while keepGoing and count < max:

    count += 1
    wx.MilliSleep(250)

    if count >= max / 2:
        (keepGoing, skip) = dlg.Update(count, "Half-time!")
    else:
        (keepGoing, skip) = dlg.Update(count)

    dlg.Destroy()
4

1 に答える 1

5

問題

imgSearch.findImages()あなたの質問は漠然としていますが、あなたのコードを見た後、あなたの問題はダイアログが開く前に完了することだと推測します。質問を編集していただければ幸いです。これが正しいかどうかがわかります。

このチュートリアルのコードを使用して、 の使用方法を示しているようwx.ProgressDialogです。残念ながら、あなたはこれに対してかなり単純なアプローチを取っています。このチュートリアルの目的は、読者にさまざまな組み込みダイアログを紹介することです。そのため、このwx.ProgressDialog例は単にメソッドを示すための単純な例であり、実装として使用するためのものではありません。

背景情報

まず、マルチスレッドとは何か、またその仕組みを理解する必要があります。コンピュータが行うことはすべて、一連の数学的操作に分解されます。コンピュータ プロセッサは、一度に 1 つの操作しか実行できません。したがって、コンピューターは一度に 1 つのことしかできません。「それは正しくない。インターネットを閲覧しながら MP3 を聴いている。それは少なくとも 2 つのことだ」と考えているかもしれません。あなたは正しく、あなたは間違っています。シェフを想像してみてください。シェフは一度にたくさんの料理を作ることができます、一度に 1 つずつしか注意を払うことができません。したがって、すべてが完了するまで、いくつかの小さなタスクを実行しながら、料理を切り替える必要があります。それがコンピュータのマルチタスクです。「料理」の代わりに、

ソリューション

ステップ 1: ねじ切り

デフォルトでは、wxPython は 1 つのスレッドのみです (これは正確には当てはまりませんが、それに従ってください)。wxPython は、次の行が実行される前に 1 行が完全に終了する必要があるように、文字通りコードを 1 行ずつ実行します。したがって、imgSearch.findImages()の実行中は他のコードは実行されず、wx.ProgressDialogを作成する前に完了する必要があります。幸いなことに、これを修正するにはいくつかの方法があります。悪いニュースは、これを修正することが非常に複雑になる可能性があることです. 私は専門家ではありませんが、「wxpython threading」を検索して、いくつかのチュートリアルを見つけることをお勧めします。このチュートリアルを見つけましたが、かなり古いものです。主なポイントは、GUIをブロックimgSearch.findImages()しないように独自のスレッドで実行する必要があるということです。

ステップ 2: 指標

では、どのようにwx.ProgressDialogに の実際のステータスを反映させますimgSearch.findImages()か? まあ、それは依存します。どれだけの作業が行われ、あとどれだけの作業が残っているかを測定するのに役立つメトリクスを見つける必要があります。あなたのコードでは、進行状況がかかるようにプログラムされているため、メトリックは時間です80 * 250ms = 20s。時間はおそらくあなたが望むものではありません。プログラムに最適なものを決定する必要がありますが、わかりやすいので「フォルダー数」の例を使用します。フォルダーの総数と、完全にスキャンしたフォルダーの数を数えます。メトリクスを初期化する方法は 2 つあります。を計算できます。max数値が小さい場合や計算が簡単な場合 (時間など)、または動的なアプローチを採用できる場合に必要です。私の場合、「フォルダー数」を正確に計算するには、画像検索自体とほぼ同じ時間がかかるため、動的が最適なオプションです。imgSearch.findImages()そのため、スキャンしたフォルダの数だけでなく、認識したフォルダの数も保持するように変更します (たとえば、開始場所に 3/0 から始まる 3 つのフォルダがある場合、最初のスキャンを開始します)。フォルダー自体にはさらに 2 つのフォルダーが含まれているため、5/0 になります。フォルダーを完全にスキャンするたびに、スキャンしたフォルダーの数に 1 を追加します。つまり、1 つのフォルダーをスキャンすると 5/1 になります。) スキャンしたフォルダの数と、スキャンするために残っているフォルダの数がわかれば、 を使用して完了率を見積もることができ# of folders scanned / total # of foldersます。1 / 5 = 0.20、したがって、私は 20% 完了していると見積もっています (次にスキャンするフォルダーにさらに 5 つのフォルダーが含まれている場合、この数は自動的に 10% に減少することに注意してください。20% を見積もりと呼んだのはそのためです)。

ステップ 3: 更新する

したがって、これimgSearch.findImages()までに独自のスレッドを作成する必要があり、完了までの距離を見積もることができるはずです。を更新する必要がありwx.ProgresDialogます。この種の問題に対する私のお気に入りの方法は、pubsubライブラリを使用することです。基本的に、imgSearch.findImages()スレッドは完了にどれだけ近づいているかを示すメッセージをときどき送信する必要があります。おそらく各フォルダの最後にあります。たぶん 3 つのフォルダー。それはあなた次第です。次に、メイン GUI のスレッドで、これらのメッセージを読み取り、それに応じて更新できるメソッドを作成する必要がありますwx.ProgressDialog

大変な作業ですが、ご冥福をお祈りいたします。

于 2012-09-03T03:26:05.997 に答える