subprocess.Popen可以工作,但任何类型的等待(调用,等待,通信)都会导致"无响应"

时间:2017-07-18 10:30:55

标签: python tkinter subprocess

这有效:

def letsExecute():
    import subprocess
    subpr = subprocess.Popen("python " + codeFile + spacedout)

这会导致程序无法响应(我在Windows上运行):

def letsExecute():
    import subprocess
    subprocess.call("python " + codeFile + spacedout)

waitcommunicate基本上任何使主进程等待子进程的东西都会导致相同的情况。我希望主进程在子进程成功完成时退出。

另外,FYI:此函数挂钩到tkinter按钮,该程序使用tkinter GUI和mainloop()。 Dunno如果这会影响这个问题,但无论如何都会让你知道。

提前致谢!

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。

subprocess.call()

  

运行args描述的命令。等待命令完成,然后返回returncode属性

wait()communicate()也是阻止功能。

改为使用poll()

subpr = subprocess.Popen(["python", codeFile, spacedout])

while subpr.poll() is None:
    print("Still working...")
    time.sleep(0.1)

由于您希望GUI线程具有响应能力,因此您可以在其他线程上启动子流程。像这样的东西,

import subprocess
import threading
import time

def letsExecute():
   t = threading.Thread(target=realExec)
   t.run()

def realExec():
   proc = subprocess.Popen(["python", codeFile, spacedout])

   while proc.poll() is None:
       print("Still working...")
       time.sleep(0.1)

答案 1 :(得分:1)

首先,为什么要在导入时尝试subprocess另一个python脚本?

无论如何,问题源于callwaitcommunicate如果subprocess参数被忽略则等待timeout的终止。由于此tkinter应用程序无法自行刷新,因此代码流无法访问mainloop

如果您有一些复杂的想法 - 请查看threadingmultiprocessingthis主题。

如果你想在子流程完成时终止主进程 - 请看看thoose片段:

<强> test.py:

import time

time.sleep(5)

<强> main.py:

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

import subprocess

class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.button = tk.Button(self, text='Start', command=self.start_test_process)
        self.button.pack()
        self.process = None

    def continuous_check(self):
        status = self.process.poll()

        if status is None:
            print('busy')
            self.after(500, self.continuous_check)
        elif status == 0:
            print('successfully finished')
            self.destroy()
        else:
            print('something went wrong')

    def start_test_process(self):
        self.process = subprocess.Popen('python test.py')
        self.continuous_check()


app = App()
app.mainloop()

这里的主要想法是mainloop可以使用pollafter方法组合的代码保持{。}}。