rust fltk-rs使变量在函数外可用(闭包)

vjhs03f7  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(81)

我是Rust的新手,我正在尝试使用fltk-rs创建一个GUI scp应用程序。我有一个变量(files),我试图在其中保存一个我想通过scp发送的文件列表。在btn_files_select.set_callback内部,关闭文件被正确保存,但在此外部,关闭文件变为空。
这就是我到目前为止所做的:

use fltk::{prelude::*, *};
use fltk_theme::{ColorTheme, WidgetTheme, ThemeType, color_themes};
use std::path::PathBuf;
use std::cell::RefCell;
use std::rc::Rc;

#[derive(Copy, Clone)]
pub enum Message {
    Send,
    Test,
}

#[derive(Clone)]
pub struct MyApp {
    app: app::App,
    main_window: window::Window,
    receiver: app::Receiver<Message>,
    input_host: input::Input,
    input_username: input::Input,
    input_password: input::SecretInput,
    files: Rc<RefCell<Vec<PathBuf>>>,
}

impl MyApp {
    pub fn new() -> Self {
        let app = app::App::default().with_scheme(app::Scheme::Base);
        let (s, receiver) = app::channel();
        let theme = ColorTheme::new(color_themes::BLACK_THEME);
        let widget_theme = WidgetTheme::new(ThemeType::AquaClassic);
        theme.apply();
        widget_theme.apply();
        let mut main_window = window::Window::default().with_size(800, 500).with_label("SSH conectivity").center_screen();
        main_window.make_resizable(true);
        let flex = group::Flex::default().with_size(300, 200).with_type(group::FlexType::Column).with_pos(100, 100);
        let _label_host = frame::Frame::default().with_size(40, 0).with_label("Hostname");
        let input_host = input::Input::default();
        let _label_username = frame::Frame::default().with_size(40, 0).with_label("User");
        let input_username = input::Input::default();
        let _label_password = frame::Frame::default().with_size(40, 0).with_label("Password");
        let input_password = input::SecretInput::default();
        let mut btn_files_select = button::Button::default().with_size(100, 30).with_label("Select files");
        flex.end();
        //let mut frame = frame::Frame::default().with_size(200, 100).with_pos(600, 200);
        let mut button_send = button::Button::default().with_size(50, 40).with_pos(150, 350).with_label("Send");
        button_send.emit(s, Message::Send);
        let mut button_test = button::Button::default().with_size(50, 40).with_pos(250, 350).with_label("Test");
        button_test.emit(s, Message::Test);
        main_window.end();
        main_window.show();
        let mut files: Vec<PathBuf> = vec![];
        let files = Rc::from(RefCell::from(files));
        btn_files_select.set_callback({let mut files = files.clone(); move |_|{
            let mut dialog = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseMultiFile);
            dialog.show();
            files = Rc::from(RefCell::from(dialog.filenames()));
            }
        });
        Self { app, main_window, receiver, input_host, input_username, input_password, files }
    }
    pub fn run(mut self) {
        while self.app.wait() {
            if let Some(msg) = self.receiver.recv() {
                match msg {
                    Message::Send => {
                        
                        println!("{:?}", self.files);
                    },
                    Message::Test => {
                        println!("Test");
                    },
                }
            }
        }
    }
}

字符串
我想让档案在结案后还能用。运行代码时,选择任何文件并单击“发送”。它将打印:RefCell {值:[] }

ni65a41a

ni65a41a1#

当你在callback中这样写:

files = Rc::from(RefCell::from(dialog.filenames()));

字符串
你忘记了共享的files,并创建了一个新的仅限本地的向量。相反,您应该更改共享值:

*files.borrow_mut() = dialog.filenames();

相关问题