使用wxwidget在while循环下移动多个文件

时间:2012-11-10 12:59:06

标签: c++ wxwidgets

我一直在为自己编写一个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"));
            }

但我写的代码似乎效率很低。移动文件需要花费大量时间,而且复制时窗口没有响应。有人请帮我改写它.. !!!!

2 个答案:

答案 0 :(得分:2)

要使应用程序窗口保持响应,但不会在单独的线程中执行文件复制的额外麻烦,请尝试使用Yield。需要照顾!

wxApp ::产量

bool Yield(bool onlyIfNeeded = false)

对窗口系统中的待处理消息进行控制。例如,当耗时的进程写入文本窗口时,这可能很有用。如果没有偶然的产量,文本窗口将无法正确更新,并且在具有协作式多任务处理的系统上,例如Windows 3.1,其他进程将无法响应。

但是,应该谨慎行事,因为屈服可能允许用户执行与当前任务不兼容的操作。在处理过程中禁用菜单项或整个菜单可以避免不必要的代码重入:请参阅:: wxSafeYield以获得更好的功能。

请注意,Yield()不会刷新消息日志。这是故意的,因为调用Yield()通常是为了快速更新屏幕并且弹出消息框对话框可能是不合需要的。如果您确实希望立即刷新日志消息(否则将在下一个空闲循环迭代期间完成),请调用wxLog :: FlushActive。

递归调用Yield()通常是一个错误,如果检测到这种情况,则会在调试版本中引发断言失败。但是,如果onlyIfNeeded参数为true,则该方法将以静默方式返回false。

答案 1 :(得分:1)

您有两种标准方法可以实现长时间运行的任务。

第一个,也是最好的,是在一个单独的后台线程中执行此任务。您可以通过将包含进度数据的wxThreadEvent轻松发布到主窗口来更新主线程中GUI控件的状态。唯一的复杂因素 - 但非常重要 - 在这种情况下是正确处理关闭窗口/应用程序终止/线程退出。

第二个,可以在紧要关头做,是在wxEVT_IDLE处理程序中逐个完成任务,并在每个步骤后调用wxIdleEvent::RequestMore()。这不像使用单独的线程那样响应,因为您仍然在处理程序执行期间阻止事件处理,并且代码需要以不同的方式重写,以便能够从中断处继续。

使用wxYield()是一个非常糟糕的主意,应该避免,除非没有其他解决方案可以实现。