Gtk-rs传递窗口作为值



Rust新手,我正在尝试使用gtk-rs按照这里的文档构建一个简单的Rust GUI。我想知道的是,是否有可能通过build_ui函数中构建的window,以便我可以从代码中的其他操作更新它。下面的代码生活在一个函数中,这个函数也做其他的事情,在函数的下面,我想访问窗口,这样我就可以添加一个新的子部件(或类似的东西)。这可能吗?如果是这样,我该怎么做呢?不幸的是,项目中没有一个例子涵盖这样的内容。

fn main() {
let app = Application::builder()
.application_id("org.gtk-rs.example")
.build();
app.connect_activate(build_ui);
let mut win: ApplicationWindow; <---- I want to store the window here to use later
fn build_ui(app: &Application) {
// Create a window and set the title
let window = ApplicationWindow::builder()
.application(app)
.title("My GTK App")
.build();

win = window; <---- 
}
// do other UI bootstrapping stuff
// when ready to mount the window
window.present();
}

感谢任何帮助,谢谢

我对Gtk-rs的操作如下:

struct Context {
wnd: Option<ApplicationWindow>,
//... other values associated to that window
}
let ctx = Context {
wnd: None,
//...
};
let ctx: Rc<RefCell<Context>> = Rc::new(RefCell::new(ctx));
app.connect_activate(clone!(
@strong ctx =>
move |app| {
let mut ctx = ctx.borrow_mut();
let window = ApplicationWindow::builder()
.application(app)
.title("My GTK App")
.build();

ctx.wnd = Some(window);
}
));

大部分连接信号克隆ctx,形成一种克隆链。

具体情况取决于您的应用程序类型:

  • 如果你的应用程序只有一个主窗口,它更容易创建它时,创建新的上下文,而不是在activate信号。这样你的wnd: Option<ApplicationWindow>就变成了更容易管理的wnd: ApplicationWindow
  • 如果你的应用程序可以有许多主窗口,那么你需要处理某种类型的列表:
struct Context {
wnds: Vec<WindowContext>,
//global state
}
struct WindowContext {
wnd: ApplicationWindow,
//local state
}

请记住,在RefCell中调用borrow_mut会给您一个独占借用。如果你试图借两次,其中一次是独家的,它会恐慌。因此,如果某个函数引发一个信号,调用另一个借用全局ctx的回调,那么您将不得不做一些舞蹈。

my_thing.connect_signal(clone!(
@strong ctx =>
move |_| {
let ctx_ = ctx.borrow_mut();
ctx_.do_something_that_that_does_not_borrow();
drop(ctx_); //<-- release the borrow!
do_something_else_that_may_borrow();
//or also:
let w = ctx.borrow().wnd.clone();
do_something_else_that_may_borrow_with_window(w);
}
));