英文:
How to react to keypress events in Go?
问题
我有一个用Go编写的REPL应用程序,应该对键盘按键事件做出反应(每个按下的键都有不同的操作),但是ReadString
在读取os.Stdin
之前需要按下<kbd>return<kbd>键:
import (
"bufio"
"os"
)
for {
reader := bufio.NewReader(os.Stdin)
key, _ := reader.ReadString('\n')
deferKey(key)
}
如何在Go中对键盘按键事件做出反应?
英文:
I have a REPL app in Go that should react to keyboard press events (distinct action for each key pressed key) but ReadString
expects for <kbd>return<kbd> key to be pressed before reading os.Stdin
:
import (
"bufio"
"os"
)
for {
reader := bufio.NewReader(os.Stdin)
key, _ := reader.ReadString('\n')
deferKey(key)
}
How can I react to key press events in Go?
答案1
得分: 5
游戏引擎通常实现这种功能。它们通常也非常平台无关(通常至少支持Windows、Linux和Mac OS X)。例如,可以尝试使用Azul3D的键盘库。
大致的逻辑如下:
watcher := keyboard.NewWatcher()
// 查询包含所有按键信息的映射
status := watcher.States()
left := status[keyboard.ArrowLeft]
if left == keyboard.Down {
// 左箭头键被按下
// 做一些操作!
}
获取当前按下的按键列表只需遍历映射并列出值为Down的按键。
英文:
Game engines commonly implement this kind of functionality. They are usually also pretty much platform agnostic (usually at least Windows, Linux, Mac OS X). Try for instance Azul3D's keyboard library.
The logic is off the top of my head something like
watcher := keyboard.NewWatcher()
// Query for the map containing information about all keys
status := watcher.States()
left := status[keyboard.ArrowLeft]
if left == keyboard.Down {
// The arrow to left is being held down
// Do something!
}
Getting a list of what keys are currently being pressed down is a matter of iterating the map through and listing the keys where value was Down.
答案2
得分: 3
这是一个关于在不同平台上实现键盘记录器的问题,根据这个类似问题的答案,有几个选项可以选择。
作者个人使用了https://github.com/MarinX/keylogger这个库。这个库写得很好,易于理解。当时,作者需要编写自己的版本来监听多个键盘,而这个代码很容易适应这个需求。需要注意的是,这个库只适用于Linux。
以下是示例代码:
import (
"github.com/MarinX/keylogger"
"github.com/sirupsen/logrus"
)
func main() {
// 查找键盘设备,不需要root权限
keyboard := keylogger.FindKeyboardDevice()
logrus.Println("Found a keyboard at", keyboard)
// 使用键盘初始化keylogger
k, err := keylogger.New(keyboard)
if err != nil {
logrus.Error(err)
return
}
defer k.Close()
events := k.Read()
// 遍历事件
for e := range events {
switch e.Type {
// EvKey用于描述键盘、按钮或其他类似键盘设备的状态变化
// 更多事件请查看input_event.go
case keylogger.EvKey:
// 如果按键被按下
if e.KeyPress() {
logrus.Println("[event] press key", e.KeyString())
}
// 如果按键被释放
if e.KeyRelease() {
logrus.Println("[event] release key", e.KeyString())
}
break
}
}
}
英文:
This answer for a similar question points to few options depending on which platform you need to implement this in.
I've personally used https://github.com/MarinX/keylogger.
It's well written and easy to understand. At the time, I had to write my own version of this library to listen to multiple keyboards, It was easy to adapt this code for that.
Note that this library is written for Linux only.
Example code:
<!-- language: go -->
import (
"github.com/MarinX/keylogger"
"github.com/sirupsen/logrus"
)
func main() {
// find keyboard device, does not require a root permission
keyboard := keylogger.FindKeyboardDevice()
logrus.Println("Found a keyboard at", keyboard)
// init keylogger with keyboard
k, err := keylogger.New(keyboard)
if err != nil {
logrus.Error(err)
return
}
defer k.Close()
events := k.Read()
// range of events
for e := range events {
switch e.Type {
// EvKey is used to describe state changes of keyboards, buttons, or other key-like devices.
// check the input_event.go for more events
case keylogger.EvKey:
// if the state of key is pressed
if e.KeyPress() {
logrus.Println("[event] press key ", e.KeyString())
}
// if the state of key is released
if e.KeyRelease() {
logrus.Println("[event] release key ", e.KeyString())
}
break
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论