在使用wxWidgets的另一个线程中显示进度指示器
问题描述:
我想知道是否可以创建一个动画进度指示器,该指示器在主线程中正在进行操作时不会被冻结。我认为可能创建第二个线程并使用它来显示一个简单的对话框(在这种情况下为wxGenericProgressDialog
)可以解决问题。我尝试了多种方法,但都失败了。有一个简单的例子:在使用wxWidgets的另一个线程中显示进度指示器
class ThreadTester : public wxThread {
public:
ThreadTester(wxMutex *mutex, wxCondition *condition)
{
m_mutex = mutex;
m_condition = condition;
}
virtual wxThread::ExitCode Entry() override {
// This is usually non-blocking operation - this window
// is by default non-modal
d = new wxGenericProgressDialog("test1", "test2", 100, 0);
wxMutexLocker lock(*m_mutex);
m_condition->Broadcast();
return nullptr;
}
private:
wxCondition *m_condition;
wxMutex *m_mutex;
wxGenericProgressDialog *d;
};
void MyFrame::PerformSomeTimeConsumingOperation(wxCommandEvent& event)
{
wxMutex mutex;
wxCondition condition(mutex);
mutex.Lock();
auto t = new ThreadTester(&mutex, &condition);
t->Run();
// Wait until showing dialog is completed
condition.Wait();
// Perform some time-consuming operation here
// Kill thread (and hide the dialog) after the operation is completed
t->Kill();
}
当我删除了这一行
d = new wxGenericProgressDialog("test1", "test2", 100, 0);
它会工作得很好。这就是为什么我开始认为使用wxWidgets创建任何对话框(甚至不需要父母)需要主线程的某种注意。这就是为什么当主线程被阻塞时,无法在任何其他线程中创建对话框。那是对的吗?有没有人获得我想要做的?我知道建议的做法是将耗时的操作转移到另一个线程,并将gui处理放在主线程中,但由于这需要重新设计应用程序的某些部分,所以我决定试一试这种方式首先。
答
你应该切换你的方法 - 在辅助线程上执行一个长时间运行的任务,并在主体中执行GUI更新/刷新。
您对问题的看法是错误的 - 线程明确存在以解决此问题 - 在主线程运行时执行长时间运行的任务。此外 - 你的方法并不能保证在wxWidgets支持的3个主要平台的任何一个上工作。底线 - 在线程中执行任务并发送通知事件以更新主要的GUI - GUI。