rustgtk4gtk-rs

Binding property from within custom GTK widget, `self` does not implement ObjectType despite being a widget


I'm using gtk-rs with GTK4. I have a custom widget representing a row in a GtkListView widget. My custom widget (MyRow) is defined exactly as done in the book (see https://github.com/gtk-rs/gtk4-rs/tree/master/book/listings/todo/1/task_row).

I want to create a binding between a property of the object contained in the model and the row widget. Following the principle of the other bindings, I have done the following:

let my_binding = object
    .bind_property("my-property", &self, "css-classes")
    .sync_create()
    .build();

However, I get the following error on compilation:

error[E0277]: the trait bound `&my_row::MyRow: gtk4::prelude::ObjectType` is not satisfied
    --> src/my_row.rs:120:42
     |
120  |             .bind_property("my-property", &self, "css-classes")
     |              -------------                ^^^^^ the trait `gtk4::prelude::ObjectType` is not implemented for `&my_row::MyRow`
     |              |
     |              required by a bound introduced by this call

The required argument type is T : ObjectType. I also tried with &self.imp(). I'm confused as to why this doesn't work, since ObjectType is supposedly implemented for all subclasses of glib::Object, which MyRow definitely is (or is it?).

What would be the correct argument to pass, and why?


Solution

  • This is basically a duplicate of the question In rust and gtk4, why does not gtk::Label satisfy gtk::Widget?

    GTK object inheritance is not a Rust feature, so an explicit cast is needed. The argument I had to pass was &self.clone().upcast::<Widget>(). Cloning is not costly as per the docs, it only increments a reference counter.

    EDIT:

    In my function, self was already a reference i.e. &self. As such, by using &self it became &&self which isn't what's needed here. So using only self works. Also, in my answer above, the cast is not actually necessary, &self.clone() also works.