我一直在为自己编写一个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"));
}
但我写的代码似乎效率很低。移动文件需要花费大量时间,而且复制时窗口没有响应。有人请帮我改写它.. !!!!
答案 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()
是一个非常糟糕的主意,应该避免,除非没有其他解决方案可以实现。