2017-08-29 27 views
0

我想知道是否可以创建一个动画进度指示器,该指示器在主线程中正在进行操作时不会被冻结。我认为可能创建第二个线程并使用它来显示一个简单的对话框(在这种情况下为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处理放在主线程中,但由于这需要重新设计应用程序的某些部分,所以我决定试一试这种方式首先。

回答

1

你应该切换你的方法 - 在辅助线程上执行一个长时间运行的任务,并在主体中执行GUI更新/刷新。

您对问题的看法是错误的 - 线程明确存在以解决此问题 - 在主线程运行时执行长时间运行的任务。此外 - 你的方法并不能保证在wxWidgets支持的3个主要平台的任何一个上工作。底线 - 在线程中执行任务并发送通知事件以更新主要的GUI - GUI。

相关问题