I'm struggling to pass a method as a callback function, when calling connect_activate()
on a gtk::Application
, as shown in the code below. I've made a closure to avoid troubles concerning the &self
argument, but now I cannot fix this lifetime issues error[E0521]: borrowed data escapes outside of associated function.
What would be the easiest (and preferably idiomatic) way to deal with this error?
I need the callbacks (not only this first one) to access the struct fields. The idea is that every widget that needs to be manipulated by the application will be accessible through the GUI
struct.
struct GUI {
app: Application,
builder: Builder
}
impl GUI {
// ... (code omitted)
pub fn config(&self) {
let callback = |app| self.on_activate(app);
self.app.connect_activate(callback);
}
pub fn on_activate<'a>(&self, app: &'a Application) {
self.builder.set_application(app);
self.builder.add_from_file(UI_FILE).expect(ERR_FAILED_LOADING_UI);
let win : ApplicationWindow = self.builder.object("win").expect(
&format!("{} {}", ERR_OBJECT_NOT_FOUND, "win"));
win.show_all();
}
}
If you are still looking for an answer, I had the same problem in a program I wrote to learn Rust, and ended up solving it by keeping the object instance in a static variable. This was OK because 1) the program is single-threaded, and 2) I know there is only a single instance which doesn't change. The static needed to be mutable because it had to be set, so I had to provide accessor functions that wrapped all accesses in an unsafe{} block.
This works, but I'm afraid it is not the best solution. I'm trying to refactor to remove the static instances. If the struct is a widget subclass and the callback returns a widget you can find it from the widget tree. In my case the object is a Window subclass, so for example on a button press I can get it from button.property("root"). For basic widget interaction this suffices, but I still have the problem tha the return is a widget, not my object, so I need to find how to upcast it.