MessageDialog在单独的线程中

时间:2014-06-24 12:41:01

标签: c++ multithreading gtkmm

在我当前的项目中,我需要在按下特定按钮时执行一些计算,当我执行这些计算时,我想显示一个Gtk::MessageDialog,它只是表明正在执行计算。所以,我像这样初始化MessageDialog(暂时忽略我实际上不需要指针):

Gtk::MessageDialog *waitdialog;
Gtk::MessageDialog dia("Processing", false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_NONE, true);
dia.set_title("Wait.");
dia.set_transient_for(*(Gtk::Window *)this);
waitdialog = &dia;

接下来我想用对话框启动一个单独的线程:

std::thread dialog_thread(wait_dialog,waitdialog);

wait_dialog方法定义如下:

void wait_dialog(Gtk::MessageDialog *dialog){
  dialog->run();
}

现在的问题是,即使主窗口变暗(因为set_transient_for),消息对话框也不可见。但是,当我没有启动单独的线程,而只是调用waitdialog->run()时,这将正确显示对话框(但会导致循环)。

所以,问题是:为什么单独线程的解决方法不起作用?我无法理解: - (

1 个答案:

答案 0 :(得分:0)

GUI组件必须保留在GUI循环中。您的长时间运行计算属于该线程。计算线程然后发回GUI线程以关闭模态对话框。此外,您应该使用glib线程而不是std :: threads。以下是我如何构建程序:

// in header, member var dispatcher used to signal GUI thread
// and our member var thread
Glib::Dispatcher m_signalDone;
Glib::Thread* m_someThread;

...

// in constructor, hook up dispatcher event
m_signalDone.connect(sigc::mem_fun(this, &MyClass::OnDone));

...

// later when ready to kick off thread...
// show dialog or progess bar or something and kick off thread...
m_someThread = Glib::Thread::create(sigc::mem_fun(*this, &MyClass::CalcMethod), true);

...

void MyClass::CalcMethod()
{
   // do your long running stuff...

   // when done signal completion back to GUI
   m_signalDone.emit();
}

...

void MyClass::OnDone()
{
    // clean up dialog or progress bar or whatever

    // kill thread
    m_currentBackUpThread->join();
    m_currentBackUpThread = NULL;
}