0

私は、ディレクトリ内で反復し、ファイルをファイルと同じ名前のディレクトリに移動する、自分用の C++ コードを書いています。

   \\\\
           void foldersFrame::OnButton2Click(wxCommandEvent& event)
            {
                wxFileName mkr;
                StaticText1->SetLabel(_("0"));
                wxString fn;
                wxString newf;
                wxDir *dir=new wxDir(TextCtrl1->GetLabel());
                bool cont = dir->GetFirst(&fn);
                while (cont)
                {
                    int mm=fn.Find('.',true);
                    newf=fn.Mid(0,mm);
                    if(! mkr.DirExists(dir->GetName()+_("\\")+fn)){
                        StaticText2->SetLabel(_("copying  ")+fn);
                        if (! mkr.DirExists(dir->GetName()+_("\\")+newf)){
                            mkr.Mkdir(dir->GetName()+_("\\")+newf);
                            if (wxCopyFile(dir->GetName()+_("\\")+fn,dir->GetName()+_("\\")+newf+_("\\")+fn)){
                                wxRemoveFile(dir->GetName()+_("\\")+fn);
                            }
                            newf=StaticText1->GetLabel();
                            long d1;
                            if(!newf.ToLong(&d1));
                            d1+=1;
                            StaticText1->SetLabel(wxString::Format(wxT("%i"),d1));
                        }
                    }
                    cont = dir->GetNext(&fn);
                }
                wxSafeShowMessage(_("Message"),_("Finished"));
            }

しかし、私が書いたコードは非常に効率が悪いようです.ファイルを移動するのに時間がかかり、コピー中にウィンドウが応答しません.誰かがそれを書き直すのを手伝ってください..!!!!

4

2 に答える 2

2

アプリケーションウィンドウの応答性を維持するために、別のスレッドでファイルコピーを実行するという余分な問題を発生させずに、Yieldを使用してみてください。ケアが必要です!

wxApp :: Yield

bool Yield(bool onlyIfNeeded = false)

ウィンドウシステムで保留中のメッセージを制御できます。これは、たとえば、時間のかかるプロセスがテキストウィンドウに書き込む場合に役立ちます。時折降伏しないと、テキストウィンドウが適切に更新されず、Windows 3.1などの協調マルチタスクを備えたシステムでは、他のプロセスが応答しません。

ただし、yieldを使用すると、ユーザーが現在のタスクと互換性のないアクションを実行できる可能性があるため、注意が必要です。処理中にメニュー項目またはメニュー全体を無効にすると、コードの不要な再入を回避できます。より良い機能については、::wxSafeYieldを参照してください。

Yield()はメッセージログをフラッシュしないことに注意してください。Yield()の呼び出しは通常、画面をすばやく更新するために行われ、メッセージボックスダイアログをポップアップすることは望ましくない場合があるため、これは意図的なものです。ログメッセージをすぐにフラッシュしたい場合(そうでない場合は、次のアイドルループの反復中に実行されます)、wxLog::FlushActiveを呼び出します。

Yield()を再帰的に呼び出すことは通常エラーであり、そのような状況が検出された場合、デバッグビルドでアサートエラーが発生します。ただし、onlyIfNeededパラメーターがtrueの場合、メソッドは代わりに黙ってfalseを返します。

于 2012-11-10T17:01:35.210 に答える
1

長時間実行されるタスクを実装するには、2つの標準的な方法があります。

最初の1つは、これまでで最も優れているのは、このタスクを別のバックグラウンドスレッドで実行することです。wxThreadEvent進行状況データを含む投稿をメインウィンドウに簡単に投稿することで、メインスレッドのGUIコントロールの状態を更新できます。この場合の唯一の問題(ただし、非常に重要な問題)は、ウィンドウ/アプリケーションの終了/スレッドの終了を正しく閉じることです。

2つ目は、ピンチで実行できるもので、wxEVT_IDLEハンドラーでタスクを1つずつ実行しwxIdleEvent::RequestMore()、各ステップの後に呼び出すことです。ハンドラーの実行中にイベント処理をブロックし、中断したところから再開できるようにコードを別の方法で書き直す必要があるため、これは別のスレッドを使用する場合ほど応答性が高くありません。

使用wxYield()することはかなり悪い考えであり、他の解決策を実装できない場合を除いて避ける必要があります。

于 2012-11-11T12:55:00.493 に答える