8

我正在尝试制作一个同时启动视图窗口(控制台)和命令行的程序。在视图窗口中,它将显示不断更新,而命令行窗口将用于raw_input()接受影响视图窗口的命令。我正在考虑为此使用线程,但我不知道如何在新的控制台窗口中启动线程。我该怎么做?

4

3 回答 3

12

我同意@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
于 2012-07-30T15:32:52.443 回答
7

与其使用控制台或终端窗口,不如重新检查您的问题。您要做的是创建一个 GUI。有许多跨平台工具包,包括 Wx 和 Tkinter,它们都有小部件可以完全满足您的需求。用于输出的文本框和用于读取键盘输入的条目小部件。另外,您可以将它们包装在带有标题、帮助、打开/保存/关闭等的漂亮框架中。

于 2012-07-29T21:14:39.690 回答
1

更新答案:

import subprocess
command = "dir"
subprocess.run(["cmd.exe", "/c", "start", f"{command}"], timeout=15)

"cmd.exe" - 如果使用 Windows,Windows 只能识别双引号。
“/c” - 在我们发送 'dir'(例如)字符串之后说 'send the Return'。
“开始” - 表示打开新的控制台窗口......即使在 Pycharm 中调试 :)
f“命令” - 我使用 f 字符串发送汇编字符串 Python3.6+
(超时可选)

于 2020-09-05T00:30:10.007 回答