New to Rust and I'm trying to build a simple Rust GUI using gtk-rs following the docs here. What I'm wondering is whether it's possible to pass around the window
that gets built in the build_ui
function, so that I can update it from other operations in my code. The following code lives inside of a function that does other stuff too, further down in the function I would like to access the window so that I can add a new child widget (or something like that). Is this possible? If so how can I go about it? Unfortunately none of the examples in the project cover something like this.
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();
}
Would appreciate any help, thanks
What I do for Gtk-rs is as follows:
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);
}
));
And then most of the connected signals clone the ctx
in a kind of clone-chain.
The details vary depending on your type of application:
activate
signal. That way your wnd: Option<ApplicationWindow>
turns into a wnd: ApplicationWindow
that is easier to manage. struct Context {
wnds: Vec<WindowContext>,
//global state
}
struct WindowContext {
wnd: ApplicationWindow,
//local state
}
Just remember that calling borrow_mut
in a RefCell
gives you an exclusive borrow. If you try to borrow twice and one of them is exclusive it will panic. So if some function raises a signal that calls another callback that borrows your global ctx
then you will have to do some dancing.
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);
}
));