You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:11:38