使用 Curses 时如何正确检测 Return 或 Enter 键 [英] How to detect Return or Enter key properly when using Curses
问题描述
我想学习 Ruby,所以我想我会尝试同时学习它和 Curses.我正在创建一个导航菜单,允许用户选择将运行系统命令的选项.
I am wanting to learn Ruby so I thought I'd try and learn it and Curses at the same time. I am creating a navigation menu that allows the user to select options which will run system commands.
我已经到了创建导航菜单的地步,我可以使用箭头键在选项之间循环.
I have gotten to the point where my navigation menu is created and I can cycle through options using the arrow keys.
现在我试图读取 Enter 键作为输入并在按下 Enter 时运行系统命令.示例:
Now I am trying to read the Enter key as input and run a system command when Enter is pressed. Example:
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 键时工作.
When the Enter key is pressed, the system command does work(kind of) but I am having a problem where the system command is also run if the option is just selected or highlighted. I only want it to work if the Enter key is pressed.
如果我把它改成
if input == 'k'
系统命令仅在按下 Enter 键时运行.它不会在突出显示或选中时运行.这就是我希望它工作的方式.
The system command only runs when the Enter key is pressed. It will not run when highlighted or selected. This is the way I want it to work.
关于如何让 Enter 键与k"键的功能相同的任何想法?
Any ideas on how I can get the Enter key to function the same as the 'k' key?
这是我的代码.
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
推荐答案
可能还有其他问题,但您可能遇到的问题是键盘上的 Enter 键通常不是什么诅咒 (ncurses) 调用 KEY_ENTER
.相反,它通常分配给数字小键盘上的Enter(当小键盘模式启用时,它会发送一个转义序列).这在捕获控制+键的正确方法中讨论过诅咒.
There may be additional problems, but the one you're likely running into is that the Enter key on your keyboard usually is not what curses (ncurses) calls KEY_ENTER
. Instead, that's usually assigned to the Enter on the numeric keypad (and it sends an escape sequence when keypad mode is enabled). That's discussed in proper way of catching control+key in ncurses.
此外,您的初始化使用
Curses.raw
在任何情况下都防止诅咒返回 KEY_ENTER
.也就是说,curses 不会识别分配给该代码的转义序列.你可能想试试
prevents curses from returning KEY_ENTER
in any case. That is, curses wouldn't recognize the escape sequence assigned to that code. You might want to try
Curses.cbreak
Curses.stdscr.keypad = 1
其中(除非未显示的内容使 KEY_UP
和 KEY_DOWN
起作用)将有助于其他 KEY_xxx
符号,以及您所在的位置期望 "ENTER" 接受换行符 \n
.这更有可能达到您的预期.
which (unless something not shown is making KEY_UP
and KEY_DOWN
work) will help with the other KEY_xxx
symbols, and where you're expecting "ENTER", to accept a newline \n
character. That's more likely to do what you expect.
进一步阅读:
这篇关于使用 Curses 时如何正确检测 Return 或 Enter 键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!