2012-07-29 113 views
7

我正在嘗試製作一個程序,該程序將同時啓動視圖窗口(控制檯)和命令行。在視圖窗口中,它會顯示常量更新,而命令行窗口將使用raw_input()接受影響視圖窗口的命令。我正在考慮爲此使用線程,但我不知道如何在新的控制檯窗口中啓動線程。我會怎麼做?在新的控制檯窗口中打開Python線程

+3

不知道,如果你能在所有的,但也有平臺之間的巨大差異。最重要的是,Windows控制檯與UNIX終端不同。你在哪個平臺上? – 2012-07-29 20:29:30

+0

我想如何在Windows和UNIX/Linux/Mac上做到這一點,並使用sys.platform進行移植。 – elijaheac 2012-07-29 20:38:06

+0

寫入更新的程序來自哪裏?你能控制它嗎? – jfs 2012-07-29 20:54:43

回答

4

而不是使用控制檯或終端窗口,重新檢查您的問題。你要做的是創建一個GUI。有許多跨平臺的工具包,包括Wx和Tkinter,它們都有部件可以完成你想要的功能。用於輸出的文本框和用於閱讀鍵盤輸入的輸入小部件。另外,你可以用標題,幫助,打開/保存/關閉等方式將它們包裝在一個很好的框架中。

9

我同意@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 
+0

我想我已經理解了你的代碼的要點。所以可以肯定的是,當你啓動子進程'p = launch_entry_console(named_pipe)',然後開始用'open(named_pipe)as file'讀取文件時,這個讀取是否完成,因爲'p'在後臺運行?如在,我已經可以使用這種方案,如果我想用一個打開的管道讀取某個文本「停止」時終止「p」。 – 2016-04-15 10:32:01

+0

是的,當您從命名管道讀取數據時,「p」進程正在運行。 – jfs 2016-04-15 10:39:03

+0

在Windows中,您可以使用'console = [「cmd.exe」,「/ c」,「start」]'。 'start'使Windows打開一個新窗口。另外,我更喜歡引用COMSPEC環境變量並使用大寫字母,如'console = [os.environ.get(「COMSPEC」,「CMD.EXE」),「/ C」,「START」]',但這只是我的風格。當然,我同意GUI比所有這些都更好。 – wecsam 2017-07-18 12:10:30