Reputation: 415
I would use ncurses but I want it to run on Windows. In C++, I could use kbhit()
and getch()
from conio to first check if a character was pressed, then get it.
I would like something similar in Rust.
Upvotes: 14
Views: 14533
Reputation: 101
You can get the keyboard events in rust without pressing enter adding as a development dependency to k_board a lightweight crate developed with the purpose of offering a listener to the keyboard in raw mode using low-level resources (it does not have dependencies like other crates), I attach how you could capture any letter from the keyboard
cargo add k_board
use k_board::{keyboard::Keyboard, keys::Keys};
fn main() {
println!("[*] I use k_board lightweight software");
println!("[ ] I use heavyweight software");
for key in Keyboard::new() {
match key {
Keys::Up => {
std::process::Command::new("clear").status().unwrap();
println!("[*] I use k_board lightweight software");
println!("[ ] I use heavyweight software");
}
Keys::Down => {
std::process::Command::new("clear").status().unwrap();
println!("[ ] I use k_board lightweight software");
println!("[*] I use heavyweight software");
}
Keys::Enter => {
break;
}
_ => {}
}
}
}
Here I attach the list of keys and events
pub enum Keys {
Up,
Down,
Left,
Right,
Enter,
Space,
Delete,
Escape,
Char(char)
F(u8),
Ctrl(char),
Alt(char),
AltGr(char),
Null,
}
Upvotes: 0
Reputation: 998
You still can do something like
extern {
fn _getch() -> core::ffi::c_char;
}
fn getch() -> char {
unsafe {
_getch() as char
}
}
Upvotes: 0
Reputation: 8961
With the crate device_query you can query the keyboard state without requiring an active window. You just need to add in your Cargo.toml
file the dependency to this crate:
[dependencies]
device_query = "0.1.0"
The usage is straightforward and similar to kbhit()
and getch()
. The difference is you'll receive a Vec
of pressed keys (Keycode
) and this Vec
will be empty if no key is pressed. A single call covers the functionality of both kbhit()
and getch()
combined.
use device_query::{DeviceQuery, DeviceState, Keycode};
fn main() {
let device_state = DeviceState::new();
loop {
let keys: Vec<Keycode> = device_state.get_keys();
for key in keys.iter() {
println!("Pressed key: {:?}", key);
}
}
}
This program will print out all pressed keys on the console. To instead just check if any key is pressed (like with kbhit()
only), you could use is_empty()
on the returned Vec<>
like this:
let keys: Vec<Keycode> = device_state.get_keys();
if !keys.is_empty(){
println!("kbhit");
}
Upvotes: 8