Rust 只要gtk应用程序运行多次,g_应用程序_parse_命令行中的断言就会失败

Rust 只要gtk应用程序运行多次,g_应用程序_parse_命令行中的断言就会失败,rust,gtk-rs,Rust,Gtk Rs,如果我想多次运行Gtk应用程序,我的Gtk rs程序就会崩溃 use gio::prelude::*; use gtk::prelude::*; static APP_ID: &'static str = "com.localserver.app"; fn build_ui(app: &gtk::Application, fallback_message: Option<&'static str>) { { let window =

如果我想多次运行Gtk应用程序,我的Gtk rs程序就会崩溃

use gio::prelude::*;
use gtk::prelude::*;

static APP_ID: &'static str = "com.localserver.app";

fn build_ui(app: &gtk::Application, fallback_message: Option<&'static str>) {
    {
        let window = gtk::ApplicationWindow::new(app);
        window.set_title("App");
        window.set_position(gtk::WindowPosition::Center);
        window.set_default_size(350, 70);

        window.add(&gtk::Label::new(Some(
            fallback_message.unwrap_or("Hello world"),
        )));

        window
    }
    .show_all();
}

fn main() {
    let args = std::env::args().collect::<Vec<_>>();
    let application: gtk::Application =
        gtk::Application::new(Some(APP_ID), Default::default()).unwrap();
    application.connect_activate(|app| build_ui(&app, None));

    for n in 1 .. 4 {
        application.run(&args);
        println!("Window loaded {} times.", n);
    }
}

是什么导致了这种情况?我如何防止这种情况?

这个问题只是对GTK中发生的情况和对象层次结构的一个简单误解

GTK的对象树以一个
应用程序开始,这个应用程序在您的案例中。然后它有一个或多个
ApplicationWindow
s,它们本身就是“窗口”。从那里开始,你所有的组件都生活在这个环境下

您已经正确地完成了此层次结构-您应该在
应用程序下创建
应用程序窗口。但是,您随后决定将此应用程序运行四次
run()
。因为它是相同的(回收的)应用程序,所以它们是相同的,并且会出错


每次考虑重新创建
应用程序
;它也遵循GTK的自然生命周期。

您的
Some(fallback\u message.unwrap\u或(“Hello world”)
可以写为:
fallback\u message.or(Some”(“Hello world”)
这可能是GTK rs中的一个问题-您永远不能在安全代码中导致segfault。诚然,这条线有点模糊,因为它发生在一个外部库中,但仍然!此外,与glib::MainLoop::run非常相似,此函数将获取应用程序运行期间的主上下文。这只能做一次。
(dbustest_rs:9805): GLib-GIO-CRITICAL **: 19:23:51.883: g_application_parse_command_line: assertion '!application->priv->options_parsed' failed
Segmentation fault (core dumped)