检测按键?
Detect keydown?
我想检测 Rust 中的 keydown 事件,然后检查是否按下了组合键,以便在此基础上执行进一步的操作。
所以在我的 Rust 应用程序中基本上支持键盘快捷键。
我查看了一些板条箱,例如 ncurses,但它们不符合我的要求...
ANSI 终端(Linux、macOS)的最佳解决方案
如果你不需要支持 Windows 那么最好的是 termion.
这是一个用于操作终端的库。您可以在其中检测按键事件,甚至 键盘快捷键 。而且它真的很轻!只有 22.78 kB(从版本 1.5.5 开始)。
这是我整理的一个快速程序,用于展示一些快捷方式。
将此代码添加到 main.rs
,将 termion = "1.5.5"
添加到 Cargo.toml
并以 cargo run
!
开头
use std::io::{stdin, stdout, Write};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
fn main() {
let stdin = stdin();
//setting up stdout and going into raw mode
let mut stdout = stdout().into_raw_mode().unwrap();
//printing welcoming message, clearing the screen and going to left top corner with the cursor
write!(stdout, r#"{}{}ctrl + q to exit, ctrl + h to print "Hello world!", alt + t to print "termion is cool""#, termion::cursor::Goto(1, 1), termion::clear::All)
.unwrap();
stdout.flush().unwrap();
//detecting keydown events
for c in stdin.keys() {
//clearing the screen and going to top left corner
write!(
stdout,
"{}{}",
termion::cursor::Goto(1, 1),
termion::clear::All
)
.unwrap();
//i reckon this speaks for itself
match c.unwrap() {
Key::Ctrl('h') => println!("Hello world!"),
Key::Ctrl('q') => break,
Key::Alt('t') => println!("termion is cool"),
_ => (),
}
stdout.flush().unwrap();
}
}
跨平台解决方案
如果您需要支持Windows和所有其他平台,那么您可以使用crossterm。这是一个相当不错的图书馆,比 termion 重得多。它是 98.06 kB(从版本 0.16.0 开始)。
这是与上面相同的程序,但使用交叉项编写。
将此代码添加到 main.rs
,将 crossterm = "0.16.0"
添加到 Cargo.toml
并尝试使用 cargo run
!
//importing in execute! macro
#[macro_use]
extern crate crossterm;
use crossterm::cursor;
use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
use crossterm::style::Print;
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType};
use std::io::{stdout, Write};
fn main() {
let mut stdout = stdout();
//going into raw mode
enable_raw_mode().unwrap();
//clearing the screen, going to top left corner and printing welcoming message
execute!(stdout, Clear(ClearType::All), cursor::MoveTo(0, 0), Print(r#"ctrl + q to exit, ctrl + h to print "Hello world", alt + t to print "crossterm is cool""#))
.unwrap();
//key detection
loop {
//going to top left corner
execute!(stdout, cursor::MoveTo(0, 0)).unwrap();
//matching the key
match read().unwrap() {
//i think this speaks for itself
Event::Key(KeyEvent {
code: KeyCode::Char('h'),
modifiers: KeyModifiers::CONTROL,
//clearing the screen and printing our message
}) => execute!(stdout, Clear(ClearType::All), Print("Hello world!")).unwrap(),
Event::Key(KeyEvent {
code: KeyCode::Char('t'),
modifiers: KeyModifiers::ALT,
}) => execute!(stdout, Clear(ClearType::All), Print("crossterm is cool")).unwrap(),
Event::Key(KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::CONTROL,
}) => break,
_ => (),
}
}
//disabling raw mode
disable_raw_mode().unwrap();
}
我不想说谎,这比 termion
解决方案更难阅读,但它的作用相同。我以前没有使用 crossterm
的经验,所以这段代码实际上可能不是最好的,但它很不错。
正在寻找一种仅检测没有任何修饰符的按键的方法(Shift、Control、Alt)?检查此简化代码:
//-- code --
loop {
//--code--
match read().unwrap() {
Event::Key(KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
}) => //--code--
}
//--code--
}
//--code--
这里重要的部分是KeyModifiers::NONE
的使用。
您可以使用 console 作为简单的跨平台解决方案。
use console::Term;
fn main() {
let stdout = Term::buffered_stdout();
'game_loop: loop {
if let Ok(character) = stdout.read_char() {
match character {
'w' => todo!("Up"),
'a' => todo!("Left"),
's' => todo!("Down"),
'd' => todo!("Right"),
_ => break 'game_loop,
}
}
}
}
上面的代码片段显示了为平台匹配常见移动字符的基本示例。
我想检测 Rust 中的 keydown 事件,然后检查是否按下了组合键,以便在此基础上执行进一步的操作。 所以在我的 Rust 应用程序中基本上支持键盘快捷键。
我查看了一些板条箱,例如 ncurses,但它们不符合我的要求...
ANSI 终端(Linux、macOS)的最佳解决方案
如果你不需要支持 Windows 那么最好的是 termion.
这是一个用于操作终端的库。您可以在其中检测按键事件,甚至 键盘快捷键 。而且它真的很轻!只有 22.78 kB(从版本 1.5.5 开始)。
这是我整理的一个快速程序,用于展示一些快捷方式。
将此代码添加到 main.rs
,将 termion = "1.5.5"
添加到 Cargo.toml
并以 cargo run
!
use std::io::{stdin, stdout, Write};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
fn main() {
let stdin = stdin();
//setting up stdout and going into raw mode
let mut stdout = stdout().into_raw_mode().unwrap();
//printing welcoming message, clearing the screen and going to left top corner with the cursor
write!(stdout, r#"{}{}ctrl + q to exit, ctrl + h to print "Hello world!", alt + t to print "termion is cool""#, termion::cursor::Goto(1, 1), termion::clear::All)
.unwrap();
stdout.flush().unwrap();
//detecting keydown events
for c in stdin.keys() {
//clearing the screen and going to top left corner
write!(
stdout,
"{}{}",
termion::cursor::Goto(1, 1),
termion::clear::All
)
.unwrap();
//i reckon this speaks for itself
match c.unwrap() {
Key::Ctrl('h') => println!("Hello world!"),
Key::Ctrl('q') => break,
Key::Alt('t') => println!("termion is cool"),
_ => (),
}
stdout.flush().unwrap();
}
}
跨平台解决方案
如果您需要支持Windows和所有其他平台,那么您可以使用crossterm。这是一个相当不错的图书馆,比 termion 重得多。它是 98.06 kB(从版本 0.16.0 开始)。
这是与上面相同的程序,但使用交叉项编写。
将此代码添加到 main.rs
,将 crossterm = "0.16.0"
添加到 Cargo.toml
并尝试使用 cargo run
!
//importing in execute! macro
#[macro_use]
extern crate crossterm;
use crossterm::cursor;
use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
use crossterm::style::Print;
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType};
use std::io::{stdout, Write};
fn main() {
let mut stdout = stdout();
//going into raw mode
enable_raw_mode().unwrap();
//clearing the screen, going to top left corner and printing welcoming message
execute!(stdout, Clear(ClearType::All), cursor::MoveTo(0, 0), Print(r#"ctrl + q to exit, ctrl + h to print "Hello world", alt + t to print "crossterm is cool""#))
.unwrap();
//key detection
loop {
//going to top left corner
execute!(stdout, cursor::MoveTo(0, 0)).unwrap();
//matching the key
match read().unwrap() {
//i think this speaks for itself
Event::Key(KeyEvent {
code: KeyCode::Char('h'),
modifiers: KeyModifiers::CONTROL,
//clearing the screen and printing our message
}) => execute!(stdout, Clear(ClearType::All), Print("Hello world!")).unwrap(),
Event::Key(KeyEvent {
code: KeyCode::Char('t'),
modifiers: KeyModifiers::ALT,
}) => execute!(stdout, Clear(ClearType::All), Print("crossterm is cool")).unwrap(),
Event::Key(KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::CONTROL,
}) => break,
_ => (),
}
}
//disabling raw mode
disable_raw_mode().unwrap();
}
我不想说谎,这比 termion
解决方案更难阅读,但它的作用相同。我以前没有使用 crossterm
的经验,所以这段代码实际上可能不是最好的,但它很不错。
正在寻找一种仅检测没有任何修饰符的按键的方法(Shift、Control、Alt)?检查此简化代码:
//-- code --
loop {
//--code--
match read().unwrap() {
Event::Key(KeyEvent {
code: KeyCode::Char('a'),
modifiers: KeyModifiers::NONE,
}) => //--code--
}
//--code--
}
//--code--
这里重要的部分是KeyModifiers::NONE
的使用。
您可以使用 console 作为简单的跨平台解决方案。
use console::Term;
fn main() {
let stdout = Term::buffered_stdout();
'game_loop: loop {
if let Ok(character) = stdout.read_char() {
match character {
'w' => todo!("Up"),
'a' => todo!("Left"),
's' => todo!("Down"),
'd' => todo!("Right"),
_ => break 'game_loop,
}
}
}
}
上面的代码片段显示了为平台匹配常见移动字符的基本示例。