Gtkmm 4.10新FileDialog异步问题:调用函数提前退出
从gtkmm 4.8迁移到4.10:FileDialog异步回调的阻塞问题
我正从gtkmm 4.8迁移至4.10,想用新的FileDialog替代旧版FileChooserDialog。旧版FileChooserDialog可以设置为等待用户关闭对话框,但测试发现调用dialog->save()的函数不会等待回调处理完成,直接提前退出。
头文件代码
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(); ~ExampleWindow() override; protected: // Signal handlers: void on_button_file(); void on_button_quit(); void on_file_dialog_save(const Glib::RefPtr<Gio::AsyncResult> &result, const Glib::RefPtr<Gtk::FileDialog> &dialog); // Child widgets: Gtk::Box m_VBox; Gtk::Box m_ButtonBox; Gtk::Button m_Button_Quit; Gtk::Button m_Button_File; }; #include "filedialog.h" ExampleWindow::ExampleWindow() : m_VBox(Gtk::Orientation::VERTICAL), m_Button_File("File"), m_Button_Quit("Quit") { set_title("FileDialog example"); set_default_size(100, 100); m_VBox.set_margin(5); set_child(m_VBox); m_VBox.append(m_ButtonBox); m_ButtonBox.append(m_Button_File); m_ButtonBox.append(m_Button_Quit); m_ButtonBox.set_margin(5); m_Button_File.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_file)); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit)); } #endif //GTKMM_EXAMPLEWINDOW_H
CPP文件代码
#include "filedialog.h" ExampleWindow::ExampleWindow() : m_VBox(Gtk::Orientation::VERTICAL), m_Button_File("File"), m_Button_Quit("Quit") { set_title("FileDialog example"); set_default_size(100, 100); m_VBox.set_margin(5); set_child(m_VBox); m_VBox.append(m_ButtonBox); m_ButtonBox.append(m_Button_File); m_ButtonBox.append(m_Button_Quit); m_ButtonBox.set_margin(5); m_Button_File.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_file)); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit)); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_file() { auto dialog = Gtk::FileDialog::create(); dialog->set_title("Testing file dialog save"); printf("Created file/save dialog\n"); dialog->save(*this, sigc::bind( sigc::mem_fun( *this, &ExampleWindow::on_file_dialog_save ), dialog ) ); printf("Exited file button handler\n"); } void ExampleWindow::on_file_dialog_save(const Glib::RefPtr<Gio::AsyncResult> &result, const Glib::RefPtr<Gtk::FileDialog> &dialog) { printf("Before save/finish call\n"); auto file = dialog->save_finish(result); printf("After save/finish call\n"); } void ExampleWindow::on_button_quit() { set_visible(false); }
程序运行输出
Created file/save dialog Exited file button handler Before save/finish call After save/finish call
可见文件按钮的处理函数提前退出,无法等待回调完成。我尝试添加信号量来阻塞等待:
修改后的文件按钮处理函数
void ExampleWindow::on_button_file() { auto dialog = Gtk::FileDialog::create(); dialog->set_title("Testing file dialog save"); printf("Created file/save dialog\n"); sem_wait(&m_dialog_semaphore); printf("Before dialog->save() call\n"); dialog->save(*this, sigc::bind( sigc::mem_fun( *this, &ExampleWindow::on_file_dialog_save ), dialog ) ); sem_wait(&m_dialog_semaphore); printf("Exited file button handler\n"); }
修改后的回调函数
void ExampleWindow::on_file_dialog_save(const Glib::RefPtr<Gio::AsyncResult> &result, const Glib::RefPtr<Gtk::FileDialog> &dialog) { printf("Before save/finish call\n"); auto file = dialog->save_finish(result); printf("After save/finish call\n"); sem_post(&m_dialog_semaphore); }
但程序冻结,无法显示对话框,仅输出:
Created file/save dialog Before dialog->save() call
看起来只有当文件按钮处理函数退出后,对话框才会显示。查看gtkmm示例代码过于简单,无法解决我的疑问,特此求助。
内容的提问来源于stack exchange,提问作者SRB
相关产品推荐
相关产品推荐

