我在Curses中创建了一个菜单,用户可以使用键盘上的'w'和's'键或上下箭头在Curses菜单中上下移动。
按下Enter键后,系统命令'ls'被调用。
我遇到的问题是当用户试图移入或移出“选项0”行时,他们必须按箭头键两次。我只希望他们必须像其他选项一样按Enter键。
有没有更好的方法我可以写下面的内容,以便用户只需按一次箭头键移动到另一个选项?
if position == 0
draw_info menu, 'You selected option 0'
input = menu.getch
if input == 13 # Curses recognizes 13 as Enter being pressed
Curses.close_screen
system "clear" or system "cls"
system 'ls'
puts "\n\nPress Enter to continue."
这是我的代码:
require 'curses'
include Curses
Curses.init_screen
Curses.curs_set(0) # Invisible cursor
Curses.start_color
Curses.noecho # echo or noecho to display user input
Curses.cbreak # do not buffer commands until Enter is pressed
Curses.raw # disable interpretation of keyboard input
Curses.nonl
Curses.stdscr.nodelay = 1
begin
# 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 == 13 # Curses recognizes 13 as Enter being pressed
Curses.close_screen
system "clear" or system "cls"
system 'ls'
puts "\n\nPress Enter to continue."
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
修改
这将允许用户只需按一次箭头键,但Curses.close_screen不会关闭屏幕,所以我可以正确运行'ls'。
require 'curses'
include Curses
Curses.init_screen
Curses.curs_set(0) # Invisible cursor
Curses.start_color
Curses.noecho # echo or noecho to display user input
Curses.cbreak # do not buffer commands until Enter is pressed
Curses.raw # disable interpretation of keyboard input
Curses.nonl
Curses.stdscr.nodelay = 1
begin
# 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 13
if position.zero?
# draw_info menu, "You hit enter."
Curses.close_screen
system "clear" or system "cls"
system 'ls'
puts "\n\nPress Enter to continue."
end
when 'x'
exit
end
position = 3 if position < 0
position = 0 if position > 3
draw_menu(menu, position)
draw_info menu, "#{position}"
end
rescue => ex
Curses.close_screen
end
答案 0 :(得分:1)
为什么不将 Enter 的捕获移动到包含其余键的case语句中?
while ch = menu.getch
case ch
when KEY_UP, 'w'
position -= 1
when KEY_DOWN, 's'
position += 1
when 13
if position.zero?
Curses.close_screen
system "clear" or system "cls"
system 'ls'
puts "\n\nPress Enter to continue."
gets # waits for the user to press enter
end
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'
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
你必须按下2个键才能离开第一个菜单选项的原因是当你'输入'第一个菜单选项时(通过使position
等于0
),你会那么提示在主循环之外的另一个角色(通过menu.getch
)。所以你需要基本上“取消”第一个选项,然后你可以随意移动。
这样做,你移动到第一个菜单选项,继续所有菜单选项需要做的事情,(draw_info
调用),然后在主循环中侦听另一个键。在这里,他们可以使用箭头键立即移出选项或按 Enter 。如果他们按Enter键,然后检查他们是否在正确的菜单项上,如果是,则进行ls
通话,否则只需忽略该键并继续照常进行。
最后,if/else
链只能是一个电话:
draw_info menu, "You selected option #{position}"
答案 1 :(得分:0)
您可以使用ungetch
功能将密钥代码推回输入 FIFO :
curses.ungetch(ch)
按 ch ,以便下一个
getch()
将返回它。 注意:在调用getch()
之前,只能推送一个 ch 。
实际上,便携式应用程序只能依靠推回一个字符。使用ncurses有一个限制,但它不止一个。