Я пытаюсь создать программу, которая запустит как окно просмотра (консоль), так и командную строку. В окне просмотра будут отображаться обновления константа, а в окне командной строки будет использоваться raw_input()
для принятия команд, которые влияют на окно просмотра. Я думаю об использовании потоков для этого, но я понятия не имею, как запустить поток в новом окне консоли. Как мне это сделать?
Ответ 1
Вместо того, чтобы использовать консоль или окно терминала, переустановите свою проблему. То, что вы пытаетесь сделать, это создать графический интерфейс. Существует множество кросс-платформенных наборов инструментов, включая Wx и Tkinter, которые имеют виджетов, чтобы делать именно то, что вы хотите. Текстовое поле для вывода и виджет ввода для чтения ввода с клавиатуры. Кроме того, вы можете обернуть их в красивый фрейм с заголовками, помочь, открыть/сохранить/закрыть и т.д.
Ответ 2
Я согласен с @stark, что это GUI.
Чисто для иллюстрации здесь не рекомендуется использовать не GUI-способ, который показывает, как это сделать, используя поток, подпроцесс и именованный канал как IPC.
Существует два сценария:
-
entry.py
: принять команды от пользователя, сделать что-то с помощью команды, передать ее именованному каналу, указанному в командной строке:#!/usr/bin/env python import sys print 'entry console' with open(sys.argv[1], 'w') as file: for command in iter(lambda: raw_input('>>> '), ''): print ''.join(reversed(command)) # do something with it print >>file, command # pass the command to view window file.flush()
-
view.py
: запустите консоль ввода, распечатайте постоянные обновления в потоке, примите ввод от именованного канала и передайте его в поток обновлений:#!/usr/bin/env python import os import subprocess import sys import tempfile from Queue import Queue, Empty from threading import Thread def launch_entry_console(named_pipe): if os.name == 'nt': # or use sys.platform for more specific names console = ['cmd.exe', '/c'] # or something else: console = ['xterm', '-e'] # specify your favorite terminal # emulator here cmd = ['python', 'entry.py', named_pipe] return subprocess.Popen(console + cmd) def print_updates(queue): value = queue.get() # wait until value is available msg = "" while True: for c in "/-\|": minwidth = len(msg) # make sure previous output is overwritten msg = "\r%s %s" % (c, value) sys.stdout.write(msg.ljust(minwidth)) sys.stdout.flush() try: value = queue.get(timeout=.1) # update value print except Empty: pass print 'view console' # launch updates thread q = Queue(maxsize=1) # use queue to communicate with the thread t = Thread(target=print_updates, args=(q,)) t.daemon = True # die with the program t.start() # create named pipe to communicate with the entry console dirname = tempfile.mkdtemp() named_pipe = os.path.join(dirname, 'named_pipe') os.mkfifo(named_pipe) #note: there should be an analog on Windows try: p = launch_entry_console(named_pipe) # accept input from the entry console with open(named_pipe) as file: for line in iter(file.readline, ''): # pass it to 'print_updates' thread q.put(line.strip()) # block until the value is retrieved p.wait() finally: os.unlink(named_pipe) os.rmdir(dirname)
Чтобы попробовать, запустите:
$ python view.py