终端菜单-上-下-输入-使用模块键盘

时间:2018-09-30 08:35:34

标签: python while-loop terminal menu keyboard-events

一周前刚开始使用python。目前,我正在尝试编写一个小型程序类,以在终端中创建菜单。想法是使用上/下键浏览菜单。您可以通过按Enter选择菜单项。我使用“键盘”模块控制按下的键。

为了使用我的课程,必须创建一个对象并通过“ add_menu”方法添加菜单项。后面提到的方法有两个参数,第一个用于菜单项的名称,第二个用于传递函数,如果按下enter键,将调用该函数。

为了检查是否按下了按键,我使用了模块键盘上的keyboard.on_press方法。如果按下了键,则方法keyboard.on_press执行菜单对象的方法handle_menu。 handle_menu方法使用名为“ controller”的列表来组织菜单项的选择。基本上,它只是一个类似于[0,0,1,0]的列表。元素为1表示当前选择的菜单项。

由于我的问题:我的菜单有一个菜单项“退出”。如果选择此选项并按Enter,则我希望整个程序停止。因此,如果按下了exit,则将属性exit从0更改为1。在我的程序的while循环中,我始终检查object.exit是否为!= 1,否则程序应结束。以某种方式,这并不总是有效。如果我从头开始立即向下滚动,而没有在其他菜单项上按Enter键,则它将起作用。但是,如果我在其他菜单项上多次按Enter键,然后转到退出菜单项,则该程序不再结束(或仅当我按Enter 10-20次时)。我有一种感觉,有时Keyboard.on_press方法和while循环在后台解耦并异步运行?我不太了解发生了什么事...

import keyboard #Using module keyboard
import os

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def start_function():
    print('Start works')

def save_function():
    print('Save works')

def option_function():
    print('Option works')

class c_menu:

def __init__ (self):
    self.exit = 0
    self.menu = []
    self.functions = []
    self.controller = []

def add_menu(self, menu, function):
    self.menu.append(menu)
    self.functions.append(function)
    if len(self.controller) == 0:
        self.controller.append(1)
    else:
        self.controller.append(0)

def start_menu(self):
    os.system('cls' if os.name == 'nt' else 'clear')
    for menu_item in range(len(self.menu)):
        if self.controller[menu_item] == 1:
            print(bcolors.WARNING + self.menu[menu_item])
        else:
            print(bcolors.OKBLUE + self.menu[menu_item])

def handle_menu(self, event):
    os.system('cls' if os.name == 'nt' else 'clear')
    if event.name == 'down':
        if self.controller.index(1) != (len(self.controller) - 1):
            self.controller.insert(0,0)
            self.controller.pop()
    elif event.name == 'up':
        if self.controller.index(1) != 0:
            self.controller.append(0)
            self.controller.pop(0)
    for menu_item in range(len(self.menu)): #printing all menu items with the right color
        if self.controller[menu_item] == 1:
            print(bcolors.WARNING + self.menu[menu_item])
        else:
            print(bcolors.OKBLUE + self.menu[menu_item])
    if event.name == 'enter':
        if self.functions[self.controller.index(1)] == 'exit':
            self.exit = 1
            return
        self.functions[self.controller.index(1)]()

main_menu = c_menu()

main_menu.add_menu('Start', start_function)
main_menu.add_menu('Save', save_function) 
main_menu.add_menu('Option', option_function)
main_menu.add_menu('Exit', 'exit')

main_menu.start_menu()

keyboard.on_press(main_menu.handle_menu)

while main_menu.exit != 1:
    pass  

1 个答案:

答案 0 :(得分:0)

我想我理解这个问题。程序实际上正常结束,但是,最后按下的“ enter”仍然在一种缓冲区(或类似的东西)中,并且在程序结束后,一次又一次地执行终端命令“ python menu.py”(它进行得如此之快,以至于程序似乎没有结束)。不幸的是,我不太明白为什么会这样。

到目前为止,我的解决方案是在程序的最后(在while循环之后)使用“ keyboard.send('ctrl + c')”。这样可以防止终端再次执行命令“ python menu.py”。