事件处理:永久发送按键事件

Event handling: sends key presss event eternally

提问人:user324885 提问时间:9/3/2023 最后编辑:cafce25user324885 更新时间:9/3/2023 访问量:36

问:

我只想在黑框中画一些对象(白色方块)并处理一些事件(按下左、下、右、上箭头)。当按下其中一些键时,物体会沿相应方向移动。但是窗口一遍又一遍地获得相同的信号,直到按下另一个键。我建议,我们有一些事件缓冲区来保存事件和函数 event_key() 返回上次发生的事件。但是如何处理一次事件,直到再次按下该键。

use fltk::draw::*;
use fltk::{prelude::*, *};
use std::cell::RefCell;
use std::rc::Rc;

fn main() {
    let app = app::App::default(); //create app
    let mut win = window::Window::default() //create window
        .with_size(350, 350);
    let mut frame = frame::Frame::default() //create frame
        .size_of_parent();

    let ww = win.w() / 2; //position of white square in thr middle of width
    let wh = win.h() / 2; //position of white square in the muddle of height
    let offset = Rc::new(RefCell::new(0)); //offset of white square
    let offset1 = offset.clone();

    //drawning wgite square
    frame.draw(move |f| {
        let offset = offset1.borrow();
        draw_rect_fill(0, 0, f.w(), f.h(), enums::Color::Black);
        draw_rect_fill(ww + *offset, wh, 10, 10, enums::Color::White);
    });

    //handle key press events
    frame.handle(move |frame, _| {
        use fltk::enums::Key;

        let mut offset = offset.borrow_mut();
        let key = app::event_key();

        match key {
            Key::Right => {
                //the right arrow is pressed
                println!("{:?}", key);
                *offset += 1;
                frame.redraw();
                app::sleep(0.0500);
                true
            }
            Key::Left => {
                //the left arrow is pressed
                println!("left");
                true
            }
            Key::Up => {
                //the up arrow is pressed
                println!("Up");
                true
            }
            Key::Down => {
                //the down arrow is presed
                println!("Down");
                true
            }
            _ => false, //ignore other events
        }
    });

    win.end();
    win.show();
    app.run().unwrap();
}
迹斑斑 FLTK

评论


答:

1赞 mo_al_ 9/3/2023 #1

您必须在 handle 方法中处理事件参数:

frame.handle(move |frame, ev| {});

您可以尝试使用以下代码吗:

use fltk::draw::*;
use fltk::{prelude::*, *};
use std::cell::RefCell;
use std::rc::Rc;

fn main() {
    let app = app::App::default(); //create app
    let mut win = window::Window::default() //create window
        .with_size(350, 350);
    let mut frame = frame::Frame::default() //create frame
        .size_of_parent();

    let ww = win.w() / 2; //position of white square in thr middle of width
    let wh = win.h() / 2; //position of white square in the muddle of height
    let offset = Rc::new(RefCell::new(0)); //offset of white square
    let offset1 = offset.clone();

    //drawning wgite square
    frame.draw(move |f| {
        let offset = offset1.borrow();
        draw_rect_fill(0, 0, f.w(), f.h(), enums::Color::Black);
        draw_rect_fill(ww + *offset, wh, 10, 10, enums::Color::White);
    });

    //handle key press events
    frame.handle(move |frame, ev| {
        use fltk::enums::Key;

        let mut offset = offset.borrow_mut();
        
        match ev {
            enums::Event::KeyDown => {
                let key = app::event_key();
                println!("{:?}", key);
                match key {
                    Key::Right => {
                        //the right arrow is pressed
                        *offset += 1;
                        frame.redraw();
                        true
                    }
                    Key::Left => {
                        *offset -= 1;
                        frame.redraw();
                        true
                    }
                    _ => false, //ignore other events
                }
            }
            enums::Event::Focus => true,
            enums::Event::Unfocus => true,
            _ => false,
        }
    });

    win.end();
    win.show();
    app.run().unwrap();
}

请注意,我们还处理 Focus 和 Unfocus,因为通常帧不会响应 KeyDown,如 FLTK 文档中所示: https://www.fltk.org/doc-1.4/events.html

评论

0赞 user324885 9/4/2023
谢谢你,兄弟。后来我明白我需要先处理KeyDown事件,我做到了,但它什么也没做。现在我知道焦点事件也必须处理。你帮了我很多。