如何应对Go中的按键事件?

时间:2014-11-29 02:16:49

标签: go

我在Go中有一个REPL应用程序应该对键盘按键事件做出反应(每个按键按键的动作不同)但ReadString期望在阅读os.Stdin之前按下返回键:

import (
    "bufio"
    "os"
)

for {
    reader := bufio.NewReader(os.Stdin)
    key, _ := reader.ReadString('\n')
    deferKey(key)
}

我如何对Go中的按键事件作出反应?

2 个答案:

答案 0 :(得分:3)

游戏引擎通常实现这种功能。它们通常也几乎与平台无关(通常至少是Windows,Linux,Mac OS X)。试试Azul3D's keyboard library

逻辑是我的头脑之类的东西,比如

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!
}

获取当前正在按下的键的列表是迭代地图并列出值为Down的键。

答案 1 :(得分:1)

对于This answer

similar question指出了几个选项,具体取决于您需要在哪个平台上实现。

我个人使用过https://github.com/MarinX/keylogger
它写得很好并且易于理解。当时,我不得不编写自己的该库版本来监听多个键盘,为此很容易修改此代码。
请注意,该库仅适用于Linux。

Example code

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
        }
    }
}