Inside startup(), It seems to access the application object via self.obj():
let window = SimpleWindow::new(&self.obj());
However, that only seems to work once. A second call (e.g. self.obj().set_app_menu()) produces:
error[E0599]: the method `add_action` exists for struct `BorrowedObject<'_, application::SpApplication>`, but its trait bounds were not satisfied
--> src/application/imp.rs:98:20
|
98 | self.obj().add_action(&action_open);
| ^^^^^^^^^^ method cannot be called on `BorrowedObject<'_, application::SpApplication>` due to unsatisfied trait bounds
I had expected self to be the object, but using that produces:
error[E0599]: the method `set_app_menu` exists for reference `&imp::SpApplication`, but its trait bounds were not satisfied
--> src/application/imp.rs:73:14
|
15 | pub struct SpApplication {
| ------------------------
| |
| doesn't satisfy `_: gtk::prelude::GtkApplicationExt`
| doesn't satisfy `imp::SpApplication: IsA<gtk::Application>`
...
73 | self.set_app_menu(Some(&app_menu));
| ^^^^^^^^^^^^ method cannot be called on `&imp::SpApplication` due to unsatisfied trait bounds
How can I access the application object (multiple times) inside startup() whilst subclassing?
You’re missing the @implements gio::ActionMap part in the glib::wrapper! macro usage. Without that it’s not known that your subclass implements that interface.
As the actionmap API is not used in that specific example it was not listed there. IMHO all the superclasses and interfaces should be listed there always, even if they are currently not used.
Thanks. That worked, but gave me a new problem. Although I’ve used the clone! macro, it is still complaining about window being borrowed after move:
error[E0382]: borrow of moved value: `window`
--> src/application/imp.rs:78:38
|
61 | let window: ApplicationWindow = builder.object("appwindow").expect("Couldn't get appwindow");
| ------ move occurs because `window` has type `ApplicationWindow`, which does not implement the `Copy` trait
...
64 | .set(window)
| ------ value moved here
...
78 | action_open.connect_activate(clone!(@weak window, @weak model => move |_, _| {
| ______________________________________^
79 | | let file_chooser = FileChooserDialog::with_buttons(
80 | | Some("Open image"),
81 | | Some(&window),
... |
96 | | file_chooser.show();
97 | | }));
| |__________^ value borrowed here after move
self.window
.set(window)
.expect("Failed to initialize application window");
with
window.set_application(Some(&self));
gives me:
error[E0277]: the trait bound `&imp::SpApplication: IsA<gtk::Application>` is not satisfied
--> src/application/imp.rs:62:32
|
62 | window.set_application(Some(&self));
| --------------- ^^^^^^^^^^^ the trait `IsA<gtk::Application>` is not implemented for `&imp::SpApplication`
| |
| required by a bound introduced by this call
Thanks for the reply. I’m new to Rust, so I’m making some beginner’s mistakes. I fixed the borrow problem by replacing:
self.window
.set(window)
.expect("Failed to initialize application window");
with:
self.window
.set(window.clone())
.expect("Failed to initialize application window");
I’ve been now able to connect the Application to the ApplicationWindow with:
app.add_window(&window);
But I don’t understand why this didn’t work instead:
window.set_application(Some(&app));
Which produced the following:
error[E0277]: the trait bound `BorrowedObject<'_, application::SpApplication>: IsA<gtk::Application>` is not satisfied
--> src/application/imp.rs:64:32
|
64 | window.set_application(Some(&app));
| --------------- ^^^^^^^^^^ the trait `IsA<gtk::Application>` is not implemented for `BorrowedObject<'_, application::SpApplication>`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `IsA<T>`:
<AboutDialog as IsA<AboutDialog>>
<AboutDialog as IsA<Bin>>
<AboutDialog as IsA<Buildable>>
<AboutDialog as IsA<Container>>
<AboutDialog as IsA<glib::Object>>
<AboutDialog as IsA<gtk::Dialog>>
<AboutDialog as IsA<gtk::Widget>>
<AboutDialog as IsA<gtk::Window>>
and 1526 others
note: required by a bound in `gtk::prelude::GtkWindowExt::set_application`
--> /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.16.2/src/auto/window.rs:958:57
|
958 | fn set_application(&self, application: Option<&impl IsA<Application>>);
| ^^^^^^^^^^^^^^^^ required by this bound in `gtk::prelude::GtkWindowExt::set_application`
The problem is that BorrowedObject does not directly implement the required traits, and Rust can’t figure out that it would all be fine after a deref because of this.