我需要你的幫助來理解我的基於新菜單的python程序中的錯誤。Python curses不接受curses.KEY_UP作爲輸入
我使用curses庫創建了一個基於菜單的python。通過接受包括特殊鍵在內的所有按鍵作爲輸入時,該程序對主菜單選項正常工作,當通過getch()
獲得用戶輸入時,但是通過子菜單列表,它無法接受特殊鍵作爲輸入。
# Increment or Decrement
elif c == curses.KEY_DOWN: # down arrow
if self.option < len(self.submenu):
self.option += 1
else: self.option = 0
elif c == curses.KEY_UP: # up arrow
if self.option > 0:
self.option -= 1
else: self.option = len(self.submenu)
所以上面的是我使用來選擇該選項的條件,但沒有輸入發送當我使用上/下箭頭鍵
我分享以下
我的全部代碼詛咒import curses, os, traceback, json
file1 = json.loads(open('/etc/ansible/org/json/tag_definition.json').read())
submenu = list(file1.keys())
cfg_dict = {'InstanceName': 'NONE',
'Environment': 'NONE',
'InstanceType':'t2.micro',
'SystemOwner':'1',
'LifeCycle':'NONE',
'DeptName':'NONE',
'Org':'NONE'}
class CursedMenu(object):
'''A class which abstracts the horrors of building a curses-based menu system'''
def __init__(self):
'''Initialization'''
self.screen = curses.initscr()
curses.noecho()
curses.cbreak()
curses.start_color()
self.screen.keypad(1)
# Highlighted and Normal line definitions
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
self.highlighted = curses.color_pair(1)
self.normal = curses.A_NORMAL
def show(self, options, title="Title", subtitle="Subtitle"):
'''Draws a menu with the given parameters'''
self.set_options(options)
self.title = title.upper()
self.subtitle = subtitle.upper()
self.selected = 0
self.draw_menu()
def set_options(self, options):
'''Validates that the last option is "Exit"'''
if options[-1] is not 'Exit':
options.append('Exit')
self.options = options
def set_submenu(self, submenu):
'''Validates that the last option is "Exit"'''
if submenu[-1] is not 'Exit':
submenu.append('Exit')
self.submenu = submenu
def draw_dict(self):
self.screen.addstr(8, 35, " "*43, curses.A_BOLD)
self.screen.addstr(10, 35," "*43, curses.A_BOLD)
self.screen.addstr(12, 35," "*43, curses.A_BOLD)
self.screen.addstr(14, 35," "*43, curses.A_BOLD)
self.screen.addstr(16, 35," "*43, curses.A_BOLD)
self.screen.addstr(18, 35," "*43, curses.A_BOLD)
self.screen.addstr(20, 35," "*43, curses.A_BOLD)
self.screen.addstr(8, 35, cfg_dict['InstanceName'], curses.A_STANDOUT)
self.screen.addstr(10, 35,cfg_dict['Environment'], curses.A_STANDOUT)
self.screen.addstr(12, 35,cfg_dict['InstanceType'], curses.A_STANDOUT)
self.screen.addstr(14, 35,cfg_dict['SystemOwner'], curses.A_STANDOUT)
self.screen.addstr(16, 35,cfg_dict['LifeCycle'], curses.A_STANDOUT)
self.screen.addstr(18, 35,cfg_dict['DeptName'], curses.A_STANDOUT)
self.screen.addstr(20, 35,cfg_dict['Org'], curses.A_STANDOUT)
self.screen.refresh()
def draw_menu(self):
'''Actually draws the menu and handles branching'''
request = ""
try:
while request is not "Exit":
self.draw()
request = self.get_user_input()
self.handle_request(request)
self.__exit__()
# Also calls __exit__, but adds traceback after
except Exception as exception:
self.__exit__()
traceback.print_exc()
def draw(self):
'''Draw the menu and lines'''
#self.screen.border(0)
self.screen.subwin(40, 80, 0, 0).box()
self.screen.addstr(2,30, self.title, curses.A_STANDOUT|curses.A_BOLD) # Title for this menu
self.screen.hline(3, 1, curses.ACS_HLINE, 78)
self.screen.addstr(4,2, self.subtitle, curses.A_BOLD) #Subtitle for this menu
# Display all the menu items, showing the 'pos' item highlighted
left = 2
for index in range(len(self.options)):
menu_name = len(self.options[index])
textstyle = self.normal
if index == self.selected:
textstyle = self.highlighted
self.screen.addstr(5, left, "%d.%s" % (index+1, self.options[index]), textstyle)
left = left + menu_name + 3
self.screen.addstr(8, 4, " Instance Name:", curses.A_BOLD)
self.screen.addstr(10, 4," Environment:", curses.A_BOLD)
self.screen.addstr(12, 4," Instance Type:", curses.A_BOLD)
self.screen.addstr(14, 4," SystemOwner:", curses.A_BOLD)
self.screen.addstr(16, 4," LifeCycle:", curses.A_BOLD)
self.screen.addstr(18, 4," Department Name:", curses.A_BOLD)
self.screen.addstr(20, 4," Org:", curses.A_BOLD)
self.draw_dict()
self.screen.refresh()
def get_user_input(self):
'''Gets the user's input and acts appropriately'''
user_in = self.screen.getch() # Gets user input
'''Enter and Exit Keys are special cases'''
if user_in == 10:
return self.options[self.selected]
if user_in == 27:
return self.options[-1]
if user_in == (curses.KEY_END, ord('!')):
return self.options[-1]
# This is a number; check to see if we can set it
if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))):
self.selected = user_in - ord('0') - 1 # convert keypress back to a number, then subtract 1 to get index
return
# Increment or Decrement
if user_in == curses.KEY_LEFT: # left arrow
self.selected -=1
if user_in == curses.KEY_RIGHT: # right arrow
self.selected +=1
self.selected = self.selected % len(self.options)
return
def handle_request(self, request):
'''This is where you do things with the request'''
if request is "Org":
self.org_func()
if request is None: return
def org_func(self):
'''Actually draws the submenu and handles branching'''
c = None
self.option = 0
self.set_submenu(submenu)
height = len(self.submenu)
while c != 10:
self.s = curses.newwin(height+2, 20, 6, 14)
self.s.box()
for index in range(len(self.submenu)):
textstyle = self.normal
if index == self.option:
textstyle = self.highlighted
self.s.addstr(index+1,1, "%d-%s" % (index+1, self.submenu[index]), textstyle)
self.s.refresh()
c = self.s.getch() # Gets user input
if c == ord('k'):
d = self.submenu[self.option]
cfg_dict['Org'] = file1[d]['Org']
# This is a number; check to see if we can set it
if c >= ord('1') and c <= ord(str(len(self.submenu)+1)):
self.option = c - ord('0') - 1 # convert keypress back to a number, then subtract 1 to get index
# Increment or Decrement
elif c == curses.KEY_DOWN: # down arrow
if self.option < len(self.submenu):
self.option += 1
else: self.option = 0
elif c == curses.KEY_UP: # up arrow
if self.option > 0:
self.option -= 1
else: self.option = len(self.submenu)
return self.option
def __exit__(self):
curses.endwin()
os.system('clear')
'''demo'''
cm = CursedMenu()
cm.show(['Instance-ID','Org','Tag'], title='Instance Launch', subtitle='Options')
如果我使用字母和數字作爲輸入,但不使用特殊鍵,它的工作原理非常好。我已經使用下面的代碼,它正在工作
elif c == ord('k'): # down arrow
if self.option < len(self.submenu):
self.option += 1
else: self.option = 0
elif c == ord('i'): # up arrow
if self.option > 0:
self.option -= 1
else: self.option = len(self.submenu)
請幫助理解爲什麼代碼不接受特殊鍵。
下面是我用
{
"Dept1": {
"Instance Name": "instance1",
"Environment": "environment1",
"SystemOwner": "Owner1",
"LifeCycle": "Lcy1",
"DeptName": "Check1",
"Org": "CSO"
}
}
需要注意的是你的問題非常想念[mcve]的*最小*部分 –
嗨韋恩,感謝提醒有關我將確保我的問題符合這裏討論的問題的最小部分。 –