使用wxWidgets在另一个线程中显示进度指示器

时间:2017-08-29 20:26:38

标签: c++ multithreading wxwidgets

我想知道是否可以创建一个动画进度指示器,当主线程中有正在进行的操作时,该指示器不会被冻结。我认为可能创建第二个线程并使用它来显示一个简单的对话框(在这种情况下为wxGenericProgressDialog)将解决问题。我尝试了多种方法,但都失败了。有一个简单的例子:

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-handling放在主线程中,但由于这需要重新设计我的应用程序的某些部分,我决定尝试一下首先这样。

1 个答案:

答案 0 :(得分:1)

您应该切换方法 - 在辅助线程上执行长时间运行的任务,并在主要方面执行GUI更新/刷新。

您对此问题的看法是错误的 - 明确存在线程来解决此问题 - 在主线程运行时执行长时间运行的任务。

此外 - 您的方法不能保证在wxWidgets支持的3个主要平台中的任何一个上工作。

底线 - 在线程中执行任务并发送通知事件以更新主要任务 - GUI。