调用cursive.run()后如何创建一个新的对话框?

问题描述 投票:0回答:1

我想从“保存”按钮处理程序内部创建并显示一个新对话框。

use std::thread;
use std::time::Duration;
use cursive::align::HAlign;
use cursive::views::{Dialog, DummyView, LinearLayout, TextView};
use cursive::Cursive;
use cursive::view::Resizable;

fn main() {
    env_logger::init();

    let mut siv = cursive::default();
    siv.add_global_callback('q', Cursive::quit);

    siv.add_layer(
        Dialog::around(
            LinearLayout::vertical()
            .child(DummyView.fixed_height(1))
            .child(TextView::new("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."))
            .child(DummyView.fixed_height(1))
        )
        .title("Parent Dialogue")
        .button("Save and Restart", save)
        .button("Cancel", |s| s.quit())
        .h_align(HAlign::Center)
    );

    siv.run();
}

fn save(siv: &mut Cursive) {
    siv.add_layer(
        Dialog::around(
            LinearLayout::vertical()
            .child(DummyView.fixed_height(1))
            .child(TextView::new("Please Wait..."))
            .child(DummyView.fixed_height(1))
        )
        .title("Restarting Service")
        .h_align(HAlign::Center)
    );
    // What can I do to get cursive to draw this Dialog on the screen,
    // but not to wait for keys etc.?

    // Do things which take time.
    // No need to respond to the UI, we just want the user to see the 
    // "please wait" dialogue until the program exits.
    thread::sleep(Duration::from_secs(10));

    siv.quit();
}

上面的代码无法显示新的对话框。我认为这是因为它是在程序启动时调用

siv::run()
之后运行的。

我如何告诉草书它应该刷新显示?

有一个

siv.runner(backend).refresh()
看起来很有希望,但我没有
backend
作为参数传递给
.runner()

rust dialog cursive
1个回答
0
投票

为了解决这个问题,我必须改变信息流。

  • siv
    现在是
    CursiveRunner<CursiveRunnable>
    ,它暴露了
    .refresh()
  • “保存”按钮现在只设置一个
    save_clicked
    标志
  • .run()
    被替换为
    loop
    ,它处理
    save_clicked
    标志。

我很想看到更好的方法。

use std::cell::Cell;
use std::rc::Rc;
use std::thread;
use std::time::Duration;
use cursive::align::HAlign;
use cursive::views::{Dialog, DummyView, LinearLayout, TextView};
use cursive::{Cursive, CursiveRunnable, CursiveRunner};
use cursive::view::Resizable;

fn main() {
    env_logger::init();

    let siv = cursive::default();
    let mut siv = siv.into_runner();

    siv.add_global_callback('q', Cursive::quit);

    let save_clicked = Rc::new(Cell::new(false));
    let save_clicked_clone = save_clicked.clone();

    siv.add_layer(
        Dialog::around(
            LinearLayout::vertical()
            .child(DummyView.fixed_height(1))
            .child(TextView::new("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."))
            .child(DummyView.fixed_height(1))
        )
        .title("Parent Dialogue")
        .button("Save and Restart", move |_s| save_clicked_clone.set(true))
        .button("Cancel", |s| s.quit())
        .h_align(HAlign::Center)
    );

    siv.refresh();
    loop {
        siv.step();
        if !siv.is_running() {
            break;
        }
        if save_clicked.get() {
            save(&mut siv);       
            break;
        }
    }
}

fn save(siv: &mut CursiveRunner<CursiveRunnable>) {
    siv.add_layer(
        Dialog::around(
            LinearLayout::vertical()
            .child(DummyView.fixed_height(1))
            .child(TextView::new("Please Wait..."))
            .child(DummyView.fixed_height(1))
        )
        .title("Restarting Service")
        .h_align(HAlign::Center)
    );
    // Get cursive to draw this Dialog on the screen,
    // but not wait for keys.
    siv.refresh();

    // Do things which take time.
    // No need to service the UI, we just want the user to see the 
    // "please waiting" dialogue until the program exits.
    thread::sleep(Duration::from_secs(3));

    siv.quit();
}
© www.soinside.com 2019 - 2024. All rights reserved.