2014-02-28 47 views
1

我已經在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變量的值,並希望將它傳遞到入口而不終止子進程。

+0

你不需要這裏的子進程。你可以使用'threading'或'multiprocessing'來運行'imacap'模塊中的代碼。 – jfs

回答

1

握住參考

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

然後,你可以做

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

如果你

print(num) in the child process 

也可以看看在模塊多。它可以通過其他方式解決問題。

+0

對於'stdout = PIPE' +1。爲避免在'p.stdout.readline()'上阻塞GUI,你可以使用'tk.createfilehandler()'或者在後臺線程中讀取](http://stackoverflow.com/a/22118914/4279) – jfs

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

+0

我甚至不知道有這樣的事情存在。非常酷。我想你甚至可以使用套接字! – User

+0

@User:它是GUI框架的一個常見功能,例如'gtk'有['io_add_watch()'](http://stackoverflow.com/a/15376317/4279),'qt'允許指定[callbacks for另外,QProcess](http://stackoverflow.com/a/22110924/4279)。 ''twisted'' ['reactor.spawnProcess()'](http://stackoverflow.com/a/5750194)和'asyncio'(Python 3.4+)['loop.subprocess_exec()'](http: //stackoverflow.com/a/20697159/4279)也允許以便攜方式異步讀取子進程輸出。 – jfs

+0

是的,套接字應該更加便攜,甚至可以[在某些系統上混合套接字和子進程](https://gist.github.com/zed/7454768)。 – jfs

相關問題