在我当前的项目中,我需要在按下特定按钮时执行一些计算,当我执行这些计算时,我想显示一个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()
时,这将正确显示对话框(但会导致循环)。
所以,问题是:为什么单独线程的解决方法不起作用?我无法理解: - (
答案 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;
}