Commands can help us executing asynchronous functions. To do this, we need to enable one of the following features: tokio, async-std, or smol. The corresponding asynchronous runtime (tokio, async-std, or smol) must also be added.
Here, we use tokio as an example.
We enable tokio feature and add tokio crate.
The dependencies of Cargo.toml should look like this:
[dependencies]
iced = { version = "0.12.1", features = ["tokio"] }
tokio = { version = "1.37.0", features = ["time"] }We use Command::perform to execute an asynchronous function.
The first parameter of Command::perform is an asynchronous function, and the second parameter is a function that returns MyAppMessage.
The MyAppMessage will be produced once the asynchronous function is done.
In the following code, we use a simple asynchronous function tokio::time::sleep.
When the asynchronous function finished, we will receive MyAppMessage::Done.
use std::time::Duration;
use iced::{
widget::{button, column, text},
Element, Task,
};
fn main() -> iced::Result {
iced::application(
"executing custom commands",
MyApp::update,
MyApp::view,
)
.run()
}
struct MyApp {
state: String,
}
impl Default for MyApp {
fn default() -> Self {
MyApp::new().0
}
}
#[derive(Debug, Clone)]
enum Message {
Execute,
Done,
}
impl MyApp {
fn new() -> (Self, Task<Message>) {
(
Self {
state: String::new(),
},
Task::none(),
)
}
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Execute => {
self.state = "Executing".into();
// Executing an asynchronous function.
return Task::perform(tokio::time::sleep(Duration::from_secs(1)), |_| {
Message::Done
});
}
Message::Done => {
self.state = "Done".into();
}
}
Task::none()
}
fn view(&self) -> Element<Message> {
column!(
button("Execute").on_press(Message::Execute),
text(self.state.as_str()),
)
.into()
}
}➡️ Next: Initializing A Different Window
📘 Back: Table of contents
