每当gtk应用程序多次运行时,在g_application_parse_command_line中断言失败

时间:2019-09-06 09:41:55

标签: 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::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);
    }
}

运行时,它将经过for循环中的第一次迭代,但最后一次崩溃:

(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)

是什么原因造成的,我该如何预防?

1 个答案:

答案 0 :(得分:2)

问题是对GTK中发生的事情和对象层次结构的简单误解。

GTK的对象树以Application开头,您以您的情况为准。然后,它具有1个或多个ApplicationWindow,它们本身就是“窗口”。从那里开始,所有组件都位于该组件下。

您已经正确完成了此层次结构-您应该在ApplicationWindow下创建Application。但是,您随后决定对该应用程序run()进行四次操作,并且在库中进行检查以查看是否以前已解析参数。因为它是同一个(回收的)应用程序,所以它们都出错了。

考虑每次都重新创建Application;它也遵循自然的GTK生命周期。