Python Функция input () не ждет, если присутствует прослушиватель клавиатуры - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь сделать консольное приложение в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...