Struct ModelRc
pub struct ModelRc<T>(/* private fields */);
Expand description
ModelRc is a type wrapper for a reference counted implementation of the Model
trait.
Models are used to represent sequences of the same data type. In .slint
code those
are represented using the [T]
array syntax and typically used in for
expressions,
array properties, and array struct fields.
For example, a property <[string]> foo
will be of type ModelRc<SharedString>
and, behind the scenes, wraps a Rc<dyn Model<Data = SharedString>>.
An array struct field will also be of type ModelRc
:
export struct AddressBook {
names: [string]
}
When accessing AddressBook
from Rust, the names
field will be of type ModelRc<SharedString>
.
There are several ways of constructing a ModelRc in Rust:
- An empty ModelRc can be constructed with
ModelRc::default()
. - A
ModelRc
can be constructed from a slice or an array using theFrom
trait. This allocates aVecModel
. - Use
ModelRc::new()
to construct aModelRc
from a type that implements theModel
trait, such asVecModel
or your own implementation. - If you have your model already in an
Rc
, then you can use theFrom
trait to convert fromRc<dyn Model<Data = T>>
toModelRc
.
§Example
use slint::{slint, SharedString, ModelRc, Model, VecModel};
use std::rc::Rc;
slint!{
import { Button } from "std-widgets.slint";
export component Example {
callback add_item <=> btn.clicked;
in property <[string]> the_model;
HorizontalLayout {
for it in the_model : Text { text: it; }
btn := Button { text: "Add"; }
}
}
}
let ui = Example::new().unwrap();
// Create a VecModel and put it in an Rc.
let the_model : Rc<VecModel<SharedString>> =
Rc::new(VecModel::from(vec!["Hello".into(), "World".into()]));
// Convert it to a ModelRc.
let the_model_rc = ModelRc::from(the_model.clone());
// Pass the model to the ui: The generated set_the_model setter from the
// the_model property takes a ModelRc.
ui.set_the_model(the_model_rc);
// We have kept a strong reference to the_model, to modify it in a callback.
ui.on_add_item(move || {
// Use VecModel API: VecModel uses the Model notification mechanism to let Slint
// know it needs to refresh the UI.
the_model.push("SomeValue".into());
});
// Alternative: we can re-use a getter.
let ui_weak = ui.as_weak();
ui.on_add_item(move || {
let ui = ui_weak.unwrap();
let the_model_rc = ui.get_the_model();
let the_model = the_model_rc.as_any().downcast_ref::<VecModel<SharedString>>()
.expect("We know we set a VecModel earlier");
the_model.push("An Item".into());
});
§Updating the Model from a Thread
ModelRc
is not Send
and can only be used in the main thread.
If you want to update the model based on data coming from another thread, you need to send back the data to the main thread
using invoke_from_event_loop
or
Weak::upgrade_in_event_loop
.
use slint::Model;
slint::slint!{
export component TestCase inherits Window {
in property <[string]> the_model;
//...
}
}
let ui = TestCase::new().unwrap();
// set a model (a VecModel)
let model = std::rc::Rc::new(slint::VecModel::<slint::SharedString>::default());
ui.set_the_model(model.clone().into());
// do some work in a thread
let ui_weak = ui.as_weak();
let thread = std::thread::spawn(move || {
// do some work
let new_strings = vec!["foo".into(), "bar".into()];
// send the data back to the main thread
ui_weak.upgrade_in_event_loop(move |ui| {
let model = ui.get_the_model();
let model = model.as_any().downcast_ref::<slint::VecModel<slint::SharedString>>()
.expect("We know we set a VecModel earlier");
model.set_vec(new_strings);
});
});
ui.run().unwrap();
Implementations§
Trait Implementations§
§impl<T> Model for ModelRc<T>
impl<T> Model for ModelRc<T>
§fn row_data(&self, row: usize) -> Option<<ModelRc<T> as Model>::Data>
fn row_data(&self, row: usize) -> Option<<ModelRc<T> as Model>::Data>
§fn set_row_data(&self, row: usize, data: <ModelRc<T> as Model>::Data)
fn set_row_data(&self, row: usize, data: <ModelRc<T> as Model>::Data)
§fn model_tracker(&self) -> &dyn ModelTracker
fn model_tracker(&self) -> &dyn ModelTracker
ModelNotify
field. Read moreAuto Trait Implementations§
impl<T> Freeze for ModelRc<T>
impl<T> !RefUnwindSafe for ModelRc<T>
impl<T> !Send for ModelRc<T>
impl<T> !Sync for ModelRc<T>
impl<T> Unpin for ModelRc<T>
impl<T> !UnwindSafe for ModelRc<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> ModelExt for Twhere
T: Model,
impl<T> ModelExt for Twhere
T: Model,
§fn row_data_tracked(&self, row: usize) -> Option<Self::Data>
fn row_data_tracked(&self, row: usize) -> Option<Self::Data>
ModelTracker::track_row_data_changes
before returning Model::row_data
. Read more§fn map<F, U>(self, map_function: F) -> MapModel<Self, F>
fn map<F, U>(self, map_function: F) -> MapModel<Self, F>
map_function
.
This is a shortcut for MapModel::new()
.§fn filter<F>(self, filter_function: F) -> FilterModel<Self, F>
fn filter<F>(self, filter_function: F) -> FilterModel<Self, F>
filter_function
.
This is a shortcut for FilterModel::new()
.§fn sort(self) -> SortModel<Self, AscendingSortHelper>
fn sort(self) -> SortModel<Self, AscendingSortHelper>
SortModel::new_ascending()
.§fn sort_by<F>(self, sort_function: F) -> SortModel<Self, F>
fn sort_by<F>(self, sort_function: F) -> SortModel<Self, F>
sort_function
.
This is a shortcut for SortModel::new()
.§fn reverse(self) -> ReverseModel<Self>where
Self: Sized + 'static,
fn reverse(self) -> ReverseModel<Self>where
Self: Sized + 'static,
ReverseModel::new()
.§impl<T> NoneValue for Twhere
T: Default,
impl<T> NoneValue for Twhere
T: Default,
type NoneType = T
§fn null_value() -> T
fn null_value() -> T
§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian()
.