#python #multithreading #command-line-interface
Вопрос:
Я пытаюсь написать приложение CLI, которое отображает данные в реальном времени и одновременно позволяет вводить команды. Это должно выглядеть примерно так:
Real-time data 1: XXXX Converted Value: XX.X% Real-time data 2: XXXX Converted Value: XX.X% Real-time data 3: XXXX Converted Value: XX.X% ... Input Cmd Here $:
где «X»обновляется в определенный период, и Input Cmd Here $:
строка остается на месте, и пользователи могут вводить команды. Я также хотел бы один раз распечатать статус выполнения команды.
Я собираю данные пользователя с помощью модуля cmd и argparse и печатаю данные в другом потоке.
import threading, cmd, time, serial class CLI(cmd.Cmd): def __init__(self): super().__init__() self.cmd_parser = argparse.ArgumentParser() self.subparser = self.cmd_parser.add_subparsers(dest='command') self.read = self.subparser.add_parser('R') self.read.add_argument("-i", type=int, nargs=3, required=True) self.read.set_defaults(func=self._send_read_cmd) def default(self, line: str) -gt; bool: """ Command parser handler """ try: args = self.cmd_parser.parse_args(line.split()) except SystemExit: return False if hasattr(args, 'func'): args.func(args) def _send_read_cmd(args): """ Send read command """ ... return 0 class Display: def __init__(self): self.ser = serial.Serial(...) def get_data(self): # Get serial data data = self.ser.read(100) #format data dict ... return data_dict def _display_thread(self): print('Entering display handling thread.') while True: real_time_data = self.get_data() print(...) # Print display lines with real-time data here time.sleep(1) def run(self): """ Spawns the command handling thread """ self._display_thread = threading.Thread(target=self._display_thread) self._display_thread.start() # Wait for thread to end self._display_thread.join() return 0 if __name__ == '__main__': display = Display() display.run() cli_app = CLI() return cli_app.cmdloop()
В этом есть несколько очевидных проблем. Прежде всего, поток отображения выводит новую строку в командной строке вместо того, чтобы просто перезаписывать текущий дисплей. Я искал некоторое время и не мог найти способ сделать то, что я хочу. Любые указания будут оценены по достоинству. Во-вторых, приглашение cmd никогда не отображается. По какой-то причине кажется, что поток CLI не запускается до тех пор, пока не завершится поток отображения. В чем может быть проблема? Я ценю любую помощь.