如何在不终止子进程的情况下在被调用进程中使用childprocess的输出?

时间:2014-02-28 19:10:10

标签: opencv python-2.7 tkinter subprocess

我在python中创建了两个模块。其中一个模块用于使用Tkinter创建GUI,第二个模块用于捕获和存储图像。当我在Tkinter模块中调用opencv模块时,它首先运行opencv模块,在释放相机后,它运行了Tkinter模块。所以我使用了子进程。 POPEN()。现在我希望将子进程输出到Tkinter模块中。使用Tkinter创建GUI的代码如下。

import sys
from Tkinter import *
import Tkinter
import subprocess
def capcam():
    command="python2 imacap.py"
    subprocess.Popen(command,shell=True)
root=Tk()
add=Frame(root)
add.grid()
root.title("Test")
capcam()
button_height=11
button_width=29
button_ipadx=2
button_ipady=2
text_box = Entry(add,justify=RIGHT,width=100, font=100)
text_box.grid(row = 0, column = 1,columnspan = 5)
text_box.insert(0, "0")
bttn_3 = Button(add, height= button_height ,width= button_width,text = "3")
bttn_3.grid(row = 3, column = 2, padx=button_ipadx, pady=button_ipady)

以下是子进程的代码。

import cv2.cv as cv
capture = cv.CaptureFromCAM(0)
num = 0
while True:
    img = cv.QueryFrame(capture)
    cv.SaveImage('pic'+str(num)+'.jpg', img)
    if num == 500:
        del(capture)
        break
    if cv.WaitKey(10) == 27:
        break
    num += 1

我想在mainprocess中运行num变量的值,并希望将它传递给入口而不终止子进程。

2 个答案:

答案 0 :(得分:1)

持有参考

p = subprocess.Popen(command,shell=True, stdout = subprocess.PIPE)

然后你可以做

num = int(p.stdout.readline()) # blocks!

如果你这样做

print(num) in the child process

另请参阅模块多处理。它可以通过其他方式解决问题。

答案 1 :(得分:1)

Can I have Tk events handled while waiting for I/O?显示了在从GUI线程读取子进程输出时如何避免阻塞。假设imacap.py中有print(num)

def read_output(self, pipe, mask):
    data = os.read(pipe.fileno(), 1 << 20)
    if not data: # eof
        root.deletefilehandler(proc.stdout)
    else:
        print("got: %r" % data)

proc = Popen(["python2", "imacap.py"], stdout=PIPE, stderr=STDOUT)
root.createfilehandler(proc.stdout, READABLE, read_output)

完整的代码示例:tkinter-read-async-subprocess-output.py演示了如何使用Tkinter读取没有线程的子进程输出。它显示GUI中的输出并在按下按钮时停止子进程。

如果tk.createfilehandler()不适用于您的系统;您可以尝试使用后台线程。有关代码示例,请参阅kill-process.py