提问人:user324885 提问时间:9/3/2023 最后编辑:cafce25user324885 更新时间:9/3/2023 访问量:36
事件处理:永久发送按键事件
Event handling: sends key presss event eternally
问:
我只想在黑框中画一些对象(白色方块)并处理一些事件(按下左、下、右、上箭头)。当按下其中一些键时,物体会沿相应方向移动。但是窗口一遍又一遍地获得相同的信号,直到按下另一个键。我建议,我们有一些事件缓冲区来保存事件和函数 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();
}
答:
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事件,我做到了,但它什么也没做。现在我知道焦点事件也必须处理。你帮了我很多。
评论