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