Gtkmm多窗口创建问题:如何实现同时打开多个窗口?
解决gtkmm多窗口应用的运行问题
你说得没错,app->run()的确是阻塞调用——它会一直运行主事件循环,直到你关闭传入的窗口,这时候应用会进入终止流程,再调用一次app->run()自然会出问题,甚至触发段错误。咱们不用多线程,只要调整一下代码逻辑就能搞定。
问题根源
当你调用app->run(*servsettings)时,GTK的主循环会一直阻塞,直到servsettings窗口被关闭。这时候GTK内部已经标记应用准备退出,资源开始释放,你再去调用app->run(*main_window),相当于在一个即将销毁的应用环境里尝试启动新的主循环,必然会引发内存错误。
正确实现方式
正确的做法是先显示所有需要的窗口,再启动一次主事件循环。主循环会自动处理所有窗口的事件,直到所有窗口关闭或者你主动退出应用。
修改后的代码大概是这样:
#include <gtkmm.h> int main(int argc, char* argv[]) { auto app = Gtk::Application::create(argc, argv, "com.yourdomain.yourapp"); auto builder = Gtk::Builder::create(); try { builder->add_from_file("../src/design.glade"); } catch (const Glib::FileError& ex) { std::cerr << "FileError: " << ex.what() << std::endl; return 1; } catch (const Gtk::BuilderError& ex) { std::cerr << "BuilderError: " << ex.what() << std::endl; return 1; } Gtk::Window* main_window = nullptr; Gtk::Window* servsettings = nullptr; builder->get_widget("main", main_window); builder->get_widget("servsettings", servsettings); if (!main_window || !servsettings) { std::cerr << "Could not get window widgets from Glade file!" << std::endl; return 1; } // 关联主窗口到应用,关闭主窗口时会退出整个应用 main_window->set_application(app); // 显示两个窗口 main_window->show_all(); servsettings->show_all(); // 只启动一次主循环,处理所有窗口的事件 return app->run(); }
关键细节说明
- 只调用一次
app->run():不需要传入具体窗口,只要有窗口处于显示状态,主循环就会持续运行。当最后一个窗口关闭时,主循环会自动退出。 - 窗口与应用关联:
main_window->set_application(app)会让主窗口成为应用的"主窗口",关闭它时会触发应用退出,其他窗口也会随之关闭。如果希望其他窗口关闭时不影响应用,可以给这些窗口设置servsettings->set_hide_on_close(true),这样关闭时只是隐藏而不是销毁窗口。 - 错误处理:添加了Glade文件加载的异常捕获,方便调试布局文件是否存在问题。
- 指针有效性检查:确保从Builder获取的窗口指针不为空,避免空指针访问。
这样修改后,你的应用会同时显示主窗口和控制面板窗口,所有事件都能正常处理,关闭主窗口时整个应用会优雅退出,不会出现段错误。
内容的提问来源于stack exchange,提问作者Jacob Garby
相关产品推荐
相关产品推荐

