Search code examples
rustslint

How to use (and change) a variable in more than one Slint callback functions in Rust?


I am learning rust as well as slint. How do I solve the problem where it tells me that folder path does not live enough and considers it borrowed until the end of the main function where it gets dropped?

And make it that I can use folder_path in a different callback function after this one?

I have tried with the variable then mutable references after reading the ownership part of the rust book. But I just can't get out of this problem. Please help. Here is the code:

use rfd::FileDialog;

slint::slint! {
    import {Button, VerticalBox } from "std-widgets.slint";

    export component App inherits Window{
        in property <string> current_folder;

        callback choose_folder_clicked <=> choose_folder_btn.clicked;

        VerticalBox {
            Text { text : "Current folder: " + current_folder; }

            choose_folder_btn := Button { text: "Choose folder"; }
        }
    }
}

fn main() {
    let mut folder_path = String::new();

    let app : App = App::new().unwrap();
    let weak = app.as_weak();

    app.on_choose_folder_clicked( {

        let app : App = weak.upgrade().unwrap();
        let fpr_mut = &mut folder_path;

        move || {
            let folder = FileDialog::new()
                .set_directory("/")
                .pick_folder();

            match folder { 
                Some(f) => *fpr_mut = f.clone().into_os_string().into_string().unwrap().into(), 
                None => (),
            }
        }
    }
    );

    app.run().unwrap();
}

After this, I would like to add an another button that opens the folder remembered inside the folder_path variable so I cant use the variable itself in the first function and move it.


Solution

  • The closure for app.on_choose_folder_clicked is expected to have a static lifetime, but since it captures &mut folder_path, it's in fact tied to the life time of main(). This will lead to compile errors.

    There are different solutions to this, but I think the most common one is to share the data via Rc and use interior mutability when trying to access the data. Like here for example with AppState: https://github.com/slint-ui/slint/blob/3ad3a4265684f22a74877aadf330667d2310388b/examples/slide_puzzle/main.rs#L176

    Each closure captures a clone of the Rc