1

My Gtk-rs program crashes if I want to run a gtk application multiple times.

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);
    }
}

When ran, it goes thorough the first iteration in the for loop at the end but crashes the next time:

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

What's causing this and how can I prevent it?

4

1 回答 1

3

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

GTK 的对象树以 开头Application,您的情况就是这样。然后它有 1 个或多个ApplicationWindows,它们本身就是“窗口”。从那里开始,您的所有组件都在此之下。

你已经正确地完成了这个层次结构——你应该在下创建你ApplicationWindow的 s Applicationrun()但是,您随后对该应用程序进行了四次决定,并且在库内部进行了一次检查,以查看之前是否已解析过参数。因为它是相同的(回收的)应用程序,所以它们是,并且会出错。

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

于 2019-09-06T09:56:40.913 回答