Я пытаюсь сделать консольное приложение в Python 3.7.7 на Linux. У меня есть меню с некоторыми опциями, и пользователь может перемещать выделение вверх и вниз, используя стрелки клавиатуры. Я использовал pynput.keyboar
модуль, и это прекрасно работает. Идея состоит в том, что когда пользователь выбирает опцию и нажимает ввод, программа просит его ввести данные (имя и фамилию). И вот в чем проблема, я использую функцию input()
, но она не ждет, когда пользователь введет имя и фамилию в консоли. Я изменил свой код и заметил, что это ошибка pynput.keyboard.Listener
. Если я просто удаляю строку при запуске Listener, input()
работает так, как ожидалось, он ожидает ввода данных пользователем. Вызов listener.stop()
до input()
и затем создание нового слушателя также не работает.
У кого-нибудь есть идеи, как решить эту проблему? Я пробовал sys.stdin.readline()
и использую модуль keyboard
с привилегиями root, но они также не работают.
Вот мой код:
class Menu:
def __init__(self, _server):
self.curInd = 0
self.enterClicked = False
self.acceptKeyboard = True
self.isRunning = False
self._server = _server
self.options = [("\t1. Dodaj pracownika", self.__addEmployee),
("\t2. Usuń pracownika", self.__removeEmployee),
("\t3. Pokaż pracowników", self.__printEmployees),
("\t4. Dodaj terminal RFID", self.__addTerminal),
("\t5. Usuń terminal RFID", self.__removeTerminal),
("\t6. Pokaż terminale", self.__printTerminals),
("\t7. Przypisz kartę do pracownika", self.__assignCard),
("\t8. Usuń przypisanie karty do pracownika", self.__removeCard),
("\t9. Generuj raport czasu pracy pracownika", self.__generateReport)]
self.listener = Listener(on_press=self.on_press, on_release=self.on_release)
self.keys = list()
pass
def printMenu(self):
optionsTemp = self.options.copy()
optionsTemp[self.curInd] = ("==>" + optionsTemp[self.curInd][0], optionsTemp[self.curInd][1])
print("Zmień opcje strzałkami góra/doł. Zatwierdź enterem. Aby wyjśc wcisnij Esc")
for i in range(0, len(optionsTemp)):
print(optionsTemp[i][0])
pass
def __printEmployees(self):
li = self._server.getEmployees()
for i in range(0, len(li)):
print(li[i])
pass
def __printTerminals(self):
li = self._server.getTerminals()
for i in range(0, len(li)):
print(li[i])
pass
def menuUp(self):
if self.curInd == 0:
self.curInd = len(self.options) - 1
else:
self.curInd -= 1
pass
def menuDown(self):
if self.curInd == len(self.options) - 1:
self.curInd = 0
else:
self.curInd += 1
pass
def choose(self):
self.listener.stop()
self.acceptKeyboard = False
function = self.options[self.curInd][1]
function() #calls __addEmployee()
self.printMenu()
self.acceptKeyboard = True
self.listener = Listener(on_press=self.on_press, on_release=self.on_release)
if not (self.listener.is_alive()):
self.listener.start()
pass
def __addEmployee(self):
name = input("Podaj Imię... ")
surname = input("Podaj nazwisko... ")
res = self._server.addEmployee(name, surname)
if res:
print("Dodano pracownika")
else:
print("Błąd, nie dodano pracownika. Prawdopodobnie pracownik już istnieje")
pass
def __removeEmployee(self):
pass
def __addTerminal(self):
pass
def __removeTerminal(self):
pass
def __assignCard(self):
pass
def __removeCard(self):
pass
def __generateReport(self):
pass
def start(self):
self.isRunning = True
if not (self.listener.is_alive()):
self.listener.start()
clear()
self.printMenu()
self.main()
#self.thread.start()
def on_press(self, key):
if self.acceptKeyboard:
if ACCEPTED_KEYS.__contains__(key):
self.keys.append(key)
pass
def on_release(self, key):
if key == Key.esc:
# Stop listener
return False
pass
def main(self): # this is the method with main loop
while self.isRunning:
self.processNextKey()
time.sleep(0.005)
pass
pass
def processNextKey(self):
if len(self.keys) > 0:
key = self.keys[0]
if not self.enterClicked:
if key == Key.up:
self.menuUp()
clear()
self.printMenu()
elif key == Key.down:
self.menuDown()
clear()
self.printMenu()
elif key == Key.esc:
self.isRunning = False
self.listener.stop()
quit(0)
elif key == Key.enter:
self.enterClicked = True
print(self.options[self.curInd][0][1:] + " Czy na pewno? Potwierdź, wciskając enter")
else:
if key == Key.enter:
self.choose()
else:
print("\nRezygnacja")
self.enterClicked = False
self.keys.pop(0)
pass
pass