Меню для терминала - Вверх - Вниз - Ввод - Использование клавиатуры модуля - PullRequest
0 голосов
/ 30 сентября 2018

Только что начал использовать python неделю назад.В данный момент я пытаюсь написать небольшой программный класс, который создает меню в терминале.Идея состоит в том, чтобы пройти через меню с помощью клавиш вверх / вниз.Вы можете выбрать пункт меню, нажав Enter.Я контролирую нажатие клавиш с помощью модуля «клавиатура».

Чтобы использовать мой класс, нужно создать объект и добавить пункты меню с помощью метода «add_menu».Последний метод имеет два аргумента: первый используется для имени пункта меню, второй - для передачи функции, которая будет вызываться в случае нажатия клавиши Enter.

В порядкечтобы проверить, была ли нажата клавиша, я использую метод keyboard.on_press с клавиатуры модуля.Если клавиша была нажата, метод keyboard.on_press выполняет метод handle_menu объекта меню.Метод handle_menu использует список с именем «controller» для организации выбора пункта меню.По сути, это просто список типа [0,0,1,0].Элемент, равный 1, указывает на текущий выбранный пункт меню.

Теперь к моей проблеме: в моем меню есть пункт меню «Выход».Если это выбрано и нажата кнопка ввода, я хочу, чтобы вся программа остановилась.Поэтому, если нажата кнопка выхода, атрибут выхода изменяется с 0 на 1. В цикле while моей программы я всегда проверяю, является ли object.exit! = 1, если нет, программа должна завершиться.Почему-то это не всегда работает.Если я сразу же прокручиваю вниз с начала, не нажимая 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 голосов
/ 30 сентября 2018

Мне кажется, я понял проблему.Программа на самом деле правильно завершается, однако последнее нажатие клавиши «enter» все еще находится в каком-то буфере (или чем-то похожем), и после завершения программы терминальная команда «python menu.py» выполняется снова и снова (идет так быстро, что похоже программа не закончилась).К сожалению, я не очень понимаю, почему это происходит.

Мое решение до сих пор, я использую "keyboard.send ('ctrl + c')" в самом конце моей программы (после цикла while),Это предотвращает повторное выполнение терминалом команды «python menu.py».

...