I’m trying to subclass ListStore in Rust, but get the error:
error[E0277]: the trait bound `gtk::ListStore: IsSubclassable<document::imp::Document>` is not satisfied
--> src/document/imp.rs:15:23
|
15 | type ParentType = gtk::ListStore;
| ^^^^^^^^^^^^^^ the trait `IsSubclassable<document::imp::Document>` is not implemented for `gtk::ListStore`
|
= help: the following other types implement trait `IsSubclassable<T>`:
ApplicationWindow
Bin
CellRenderer
CellRendererAccel
CellRendererCombo
CellRendererPixbuf
CellRendererProgress
CellRendererSpin
and 31 others
note: required by a bound in `gtk::subclass::prelude::ObjectSubclass::ParentType`
--> /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/subclass/types.rs:552:22
|
552 | type ParentType: IsSubclassable<Self>
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `gtk::subclass::prelude::ObjectSubclass::ParentType`
am I missing an @implements or have I got something else wrong?
The snippet is:
#[glib::object_subclass]
impl ObjectSubclass for Document {
const NAME: &'static str = "Document";
type Type = super::Document;
type ParentType = gtk::ListStore;
}
And if I do so, and want one of the columns to contain Pixbufs, what ParamSpec do I use, as there isn’t a ParamSpecPixbuf?
Edit: Sorry for the noise, it seems that ParamSpecObject works with type Pixbuf::static_type().
But the bindings panic at my_tree_view.set_model(Some(&my_subclassed_model));:
thread 'main' panicked at 'assertion failed: self.is::<T>()', /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/object.rs:125:23
stack backtrace:
0: rust_begin_unwind
at /usr/src/rustc-1.63.0/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:142:14
2: core::panicking::panic
at /usr/src/rustc-1.63.0/library/core/src/panicking.rs:48:5
3: glib::object::Cast::unsafe_cast_ref
at /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/object.rs:280:9
4: glib::object::Cast::upcast_ref
at /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/object.rs:125:18
5: <scantpaper::document::Document as core::convert::AsRef<gtk::auto::tree_model::TreeModel>>::as_ref
at /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.16.7/src/object.rs:1290:17
6: <O as gtk::auto::tree_view::TreeViewExt>::set_model::{{closure}}
at /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.16.2/src/auto/tree_view.rs:2061:31
7: core::option::Option<T>::map
at /usr/src/rustc-1.63.0/library/core/src/option.rs:929:29
8: <O as gtk::auto::tree_view::TreeViewExt>::set_model
at /home/jeff/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.16.2/src/auto/tree_view.rs:2061:17
I assume that @implements gio::ListModel, gtk::TreeModel is not enough.
That’s not going to happen, but that will sooner or later get fixed in the Python bindings. Creating a subclass of the ListStore is not supported and can break in unexpected ways. Use composition instead of subclassing for what you want to do here, or even better implement the model yourself around the sqlite API instead of having effectively two models in place.
Oh, wait: I misread, and I thought you were trying to subclass gio::ListStore. Sorry.
gtk::ListStore is derivable, but in order to derive it you need to do a bunch of stuff like setting up the columns inside the instance initialization function. In practice, it’s very messy and there’s no real point in doing so.
Additionally, writing new code in GTK3—especially with the Rust bindings—isn’t really recommended; The GtkTreeView and friends API has just been deprecated in the main development branch (which will be released as GTK 4.10). For newly written code, the recommendation is to use GTK 4, the list view widgets, and the list model API from GIO.