MessageDialog 在单独的线程中
Posted
技术标签:
【中文标题】MessageDialog 在单独的线程中【英文标题】:MessageDialog in separate thread 【发布时间】:2014-06-24 12:41:00 【问题描述】:在我当前的项目中,当按下特定按钮时,我需要执行一些计算,并且在执行这些计算时,我想显示一个 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()
时,这将正确显示对话框(但会导致循环)。
所以,问题是:为什么使用单独线程的解决方法不起作用?我无法理解这一点:-(
【问题讨论】:
是否允许在主线程之外显示 UI?你希望通过这个实现什么?线程中的模态对话框只会阻塞该线程。是否要阻止该线程并让主线程保持响应? 当我将按钮与我的计算连接时,用户界面只是冻结(这是一个坏主意,因为用户可能会觉得程序已损坏)我的想法是打开一个 MessageDialog(没有按钮),这只是说明程序正在执行一些计算,并在计算完成后释放该 MessageDialog。我无法在主线程中打开那个 MessageDialog,因为它被阻塞了,我无法进行计算,所以我想把它放在它自己的线程中...... 我现在的解决方案是相反的:将计算放入它自己的线程并让主线程被阻塞......但是,我觉得我应该寻找更好的解决方案,因为我仍然必须将对话框传递给计算线程,以便稍后释放它)... 这听起来完全不对。不要阻塞主线程。它是用于用户界面的。将长时间运行的东西放在不同的线程中。 【参考方案1】: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;
【讨论】:
谢谢 :-) 您的回答让我更清楚(理论上),尽管我仍然必须尝试以这种方式实现它。现在有点晚了,所以我明天试试,但我已经领先了一大步……:-)以上是关于MessageDialog 在单独的线程中的主要内容,如果未能解决你的问题,请参考以下文章
JOptionPane MessageDialog 在java中显示数组的数据
win10 UWP MessageDialog 和 ContentDialog
win10 UWP MessageDialog 和 ContentDialog
如何在 QML 中设置 MessageDialog 的默认按钮?
背水一战 Windows 10 (37) - 控件(弹出类): MessageDialog, ContentDialog