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

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

我只想在黑框中绘制一些对象(白色方块)并处理一些事件(左、下、右、上箭头被按下)。当按下其中一些键时,对象会按照相应的方向移动。但是窗口一遍又一遍地收到相同的信号,直到按下另一个键为止。我建议,我们有一些事件缓冲区来保存事件,并且函数 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();
}
rust fltk
1个回答
0
投票

您必须在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

© www.soinside.com 2019 - 2024. All rights reserved.