7

Estoy intentando hacer un programa que abrirá una ventana de vista (consola) y una línea de comando. En la ventana de vista, mostraría actualizaciones constantes, mientras que la ventana de línea de comandos usaría raw_input() para aceptar comandos que afectan la ventana de visualización. Estoy pensando en usar hilos para esto, pero no tengo idea de cómo lanzar un hilo en una nueva ventana de consola. ¿Como podría hacerlo?Abrir un hilo de Python en una nueva ventana de consola

+3

No estoy seguro si se puede en absoluto, pero hay enormes diferencias entre plataformas. Lo más importante, la consola de Windows es diferente de los terminales UNIX. ¿En qué plataforma estás? –

+0

Me gustaría saber cómo hacerlo tanto en Windows como en UNIX/Linux/Mac, y usar sys.platform para ser portátil. – elijaheac

+0

De dónde viene el programa que escribe las actualizaciones. ¿Puedes controlarlo? – jfs

Respuesta

4

En lugar de utilizar una consola o una ventana de terminal, vuelva a examinar su problema. Lo que intenta hacer es crear una GUI. Hay una serie de kits de herramientas multiplataforma que incluyen Wx y Tkinter que tienen widgets para hacer exactamente lo que usted desea. Un cuadro de texto para la salida y un widget de entrada para leer la entrada del teclado. Además, puede envolverlos en un bonito marco con títulos, ayuda, abrir/guardar/cerrar, etc.

9

Estoy de acuerdo con @stark una GUI es la manera.

Puramente a modo de ejemplo, aquí hay un no recomendado que no es GUI manera que muestra cómo hacerlo usando un hilo, un subproceso y un conducto con nombre como IPC.

Hay dos guiones:

  • entry.py: aceptar comandos de un usuario, hacer algo con el comando, pasarlo a la canalización con nombre dado en la línea de comandos:

    #!/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: Inicie la consola de entrada, imprima actualizaciones constantes en una secuencia, acepte la entrada de la tubería con nombre y páselo al subproceso de actualizaciones:

    #!/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) 
    

probarlo, ejecute:

$ python view.py 
+0

Creo que he entendido la esencia de tu código. Entonces, para estar seguro, cuando lanzó el subproceso 'p = launch_entry_console (named_pipe)' y luego comenzó a leer el archivo usando 'con open (named_pipe) como archivo', ¿esta lectura se realiza cuando' p' se ejecuta en segundo plano? Como en, ya puedo usar este esquema si quiero terminar 'p' cuando un cierto texto 'stop' se lee con la tubería abierta. –

+0

Sí, el proceso 'p' se está ejecutando mientras está leyendo desde la tubería con nombre. – jfs

+0

En Windows, usaría 'console = [" cmd.exe ","/c "," start "]'. El 'start' hace que Windows abra una nueva ventana. Además, prefiero hacer referencia a la variable de entorno COMSPEC y usar letras mayúsculas, como en 'console = [os.environ.get (" COMSPEC "," CMD.EXE "),"/C "," START "]', pero ese es solo mi estilo. Por supuesto, estoy de acuerdo en que una GUI sería una mejor solución que todo esto. – wecsam

Cuestiones relacionadas