【问题标题】:How to detect Return or Enter key properly when using Curses使用 Curses 时如何正确检测 Return 或 Enter 键
【发布时间】:2017-08-06 20:18:17
【问题描述】:

我想学习 Ruby,所以我想我会尝试同时学习它和 Curses。我正在创建一个导航菜单,允许用户选择将运行系统命令的选项。

我已经创建了导航菜单,我可以使用箭头键循环浏览选项。

现在我正在尝试将 Enter 键读取为输入,并在按下 Enter 时运行系统命令。示例:

    input = menu.getch
    if input == ENTER

  position = 3 if position < 0
  position = 0 if position > 3
  draw_menu(menu, position)
  if position == 0
    draw_info menu, 'You selected option 0'
    input = menu.getch
    if input == ENTER
      menu.clear
      menu.refresh
      puts (system 'ls')

    end

当按下 Enter 键时,系统命令确实有效(有点),但我遇到了一个问题,即如果刚刚选择或突出显示该选项,系统命令也会运行。我只希望它在按下 Enter 键时工作。

如果我把它改成

    if input == 'k'

系统命令仅在按下 Enter 键时运行。突出显示或选择时不会运行。这就是我希望它工作的方式。

关于如何让 Enter 键与“k”键功能相同的任何想法?

这是我的代码。

require 'curses'
include Curses

# Top Lie
SCREEN_WIDTH       = 90
HEADER_HEIGHT      = 4
HEADER_WIDTH       = SCREEN_WIDTH

# Bottom Line
SCREEN_WIDTH2      = 90
HEADER_HEIGHT2      = 1
HEADER_WIDTH2       = SCREEN_WIDTH2

Curses.init_screen
Curses.curs_set(0)  # Invisible cursor

Curses.start_color

Curses.noecho # echo or noecho to display user input
Curses.nonl
Curses.raw
Curses.stdscr.nodelay = 1

Curses.init_pair(1, Curses::COLOR_WHITE, Curses::COLOR_BLUE)
Curses.init_pair(2, Curses::COLOR_WHITE, Curses::COLOR_BLUE)

begin

  # Top Line
  header_window = Curses::Window.new(HEADER_HEIGHT, HEADER_WIDTH, 0, 0)   # (height, width, top, left)
  header_window.color_set(1)
  header_window << "Curses example".center(HEADER_WIDTH)
  header_window.refresh

  # Bottom Line
  header2_window = Curses::Window.new(HEADER_HEIGHT, HEADER_WIDTH, 23, 0)
  header2_window.color_set(2)
  header2_window << "Curses example".center(HEADER_WIDTH)
  header2_window.refresh

  # Building a static window

    def draw_menu(menu, active_index=nil)
      ["This is option 0.", "This is option 1.", "This is option 2.", "This is option 3."].each_with_index do |element, index|
      # "w" for word array
      # It's a shortcut for arrays
        menu.setpos(index + 1, 1)
        menu.attrset(index == active_index ? A_STANDOUT : A_NORMAL)
        menu.addstr("#{index} - %-10s" % element)   # %-Xs makes sure array words line up evenly if you place index after element
                                                    # you can change 17 to another number
      end
      menu.setpos(5, 1)
    end

    def draw_info(menu, text)
      menu.setpos(6, 1)  # sets the position of move up and down
                         # for example, menu.setpos(1, 10) moves to another
                         # location
      menu.attrset(A_NORMAL)
      menu.addstr text
    end

    position = 0

    menu = Window.new(20, 70, 2, 2)  # (height, width, top, left)
    menu.keypad = true  # enable keypad which allows arrow keys
    #menu.box('|', '-')
    draw_menu(menu, position)
    while ch = menu.getch
      stdscr.keypad = true
      case ch
      when KEY_UP, 'w'
        #draw_info menu, 'move up'
        position -= 1
      when KEY_DOWN, 's'
        #draw_info menu, 'move down'
        position += 1
      when 'x'
        exit
      end
      position = 3 if position < 0
      position = 0 if position > 3
      draw_menu(menu, position)
      if position == 0
        draw_info menu, 'You selected option 0'
        input = menu.getch
        if input == 'k'  # I want this to be ENTER
            menu.clear
            menu.refresh
            puts (system 'ls')  # This does not work well.  I need to fix it.

        end
      elsif position == 1
        draw_info menu, 'You selected option 1'
      elsif position == 2
        draw_info menu, 'You selected option 2'
      else position == 3
        draw_info menu, 'You selected option 3'
      end       
    end

rescue => ex
  Curses.close_screen
end

【问题讨论】:

    标签: ruby ncurses curses


    【解决方案1】:

    可能还有其他问题,但您可能遇到的问题是键盘上的 Enter 键通常不是 curses (ncurses) 调用的 KEY_ENTER。相反,它通常分配给 数字键盘 上的 Enter (当启用 keypad 模式时,它会发送一个转义序列)。 proper way of catching control+key in ncurses 对此进行了讨论。

    另外,你的初始化使用

    Curses.raw
    

    防止curses 在任何情况下返回KEY_ENTER。也就是说,curses 不会识别分配给该代码的转义序列。你可能想试试

    Curses.cbreak
    Curses.stdscr.keypad = 1
    

    其中(除非未显示的东西使 KEY_UPKEY_DOWN 工作)将有助于其他 KEY_xxx 符号,以及您期望 “ENTER” 接受换行 \n 字符。这更有可能达到您的预期。

    进一步阅读:

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 2010-11-02
      • 1970-01-01
      • 2012-10-18
      • 2018-07-21
      • 2017-12-11
      • 2021-02-16
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多