2012-11-20 25 views
1

背景:
*我创建使用的Tkinter(便携式PYscripter,蟒蛇v2.7.3)
*这个程序将充当一个批次的模拟工作选择器+调度前端,一个商业方程求解程序
*程序需要允许用户选择一堆文件来模拟,顺序,一前一后。
*它还需要有设施从现有的/正在运行的任务列表修改(添加/删除)工作。
*每个模拟肯定会几个小时运行。
*模拟输出将在单独的程序来查看和我不需要任何管道输出。当需要时,将从GUI调用外部查看器。
按顺序使用运行Tkinter的和Python外部独立的进程

***我有一个主界面窗口,它允许用户:
选择作业文件,提交作业,查看日志提交,停止正在运行的任务(一个接一个)
上述效果很好。

问题:
*如果我使用subprocess.Popen(“命令”):所有的模拟输入文件在同一时间推出。它必须是顺序的(由于许可证和内存限制)

*如果我使用subprocess.call(“”)或wait()方法,则GUI挂起,并且没有停止/添加/修改的范围工作清单。即使“作业提交”命令位于独立窗口上,父窗口也会一直挂起,直到作业完成。

问题1:
*我如何按顺序启动仿真作业(如subprocess.call),并允许主界面窗口的工作列表修改或停止作业的目的起作用?
的工作是在一个列表中,使用“askopenfilenames”拍摄,然后运行使用For循环。

守则的相关部分:

cfx5solvepath=r"c:\XXXX" 
def file_chooser_default(): 
    global flist1 
    flist1=askopenfilename(parent = root2, filetypes =[('.def', '*.def'),('All', '*.*'),('.res', '*.res')], title ="Select Simulation run files...", multiple = True)[1:-1].split('} {') 

def ext_process(): 
    o=list(flist1) 
    p=list(flist1) 
    q=list(flist1) 
    i=0 
    while i < len(flist1): 
     p[i]='"%s" -def "%s"'%(cfx5solvepath,flist1[i]) 
     i+=1 
    i=0 
    while i < len(p): 
     q[i]=subprocess.call(p[i]) 
     i+=1 

root2 = Tk() 
root2.minsize(300,300) 
root2.geometry("500x300") 
root2.title("NEW WINDOW") 
frame21=Frame(root2, borderwidth=3, relief="solid").pack() 
w21= Button(root2,fg="blue", text="Choose files to submit",command=file_chooser_default).pack() 
w2a1=Button(root2,fg="white", text= 'Display chosen file names and order', command=lambda:print_var(flist1)).pack() 
w2b1= Button (root2,fg="white", bg="red", text="S U B M I T", command=ext_process).pack() 
root2.mainloop() 

请让我知道如果你需要任何东西。期待你的帮助。

* 编辑*
关于将通过@Tim建议的修改,该GUI是无牵无挂。由于与主解算器程序相关联的特定子程序可以停止作业,因此我可以使用正确的命令停止作业。

一旦当前正在运行的作业停止,列表中的下一个作业启动,自动,因为我希望。

这是用于停止作业的代码:

def stop_select(): #Choose the currently running files which are to be stopped 
    global flist3 
    flist3=askdirectory().split('} {') 

def sim_stop(): #STOP the chosen simulation 
    st=list(flist3) 
    os.chdir("%s"%flist3[0]) 
    st= subprocess.call('"%s" -directory "%s"'%(defcfx5stoppath,flist3[0])) 
    ret1=tkMessageBox.showinfo("INFO","Chosen simulation stopped successfully") 
    os.chdir("%s" %currentwd) 



问题2: *一旦上述工作完成后,使用start_new_thread,GUI不响应。当作业在后台运行时,GUI工作。但start_new_thread文档说该线程应该在函数返回时静默地退出。

*此外,我有一个HTML日志文件,在每个作业完成时写入/更新。当我使用start_new_thread时,日志文件内容仅在所有作业完成后才可见。然而,内容和时间戳是正确的。在不使用start_new_thread的情况下,我能够刷新HTML文件以获取更新的提交日志。

***使用任务管理器退出GUI程序几次,我突然无法使用start_new_thread函数!我曾尝试重新安装PYscripter并重新启动计算机。我无法找出任何明显的回溯,这是:

Traceback (most recent call last): 
File "<string>", line 532, in write 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\protocol.py", line 439, in _async_request 
seq = self._send_request(handler, args) 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\protocol.py", line 229, in _send_request 
self._send(consts.MSG_REQUEST, seq, (handler, self._box(args))) 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\protocol.py", line 244, in _box 
if brine.dumpable(obj): 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\brine.py", line 369, in dumpable 
return all(dumpable(item) for item in obj) 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\brine.py", line 369, in <genexpr> 
return all(dumpable(item) for item in obj) 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\brine.py", line 369, in dumpable 
return all(dumpable(item) for item in obj) 
File "C:\Portable Python 2.7.3.1\App\lib\site-packages\rpyc\core\brine.py", line 369, in <genexpr> 
return all(dumpable(item) for item in obj) 
File "C:\Portable Python 2.7.3.1\App\Python_Working_folder\v350.py", line 138, in ext_process 
q[i]=subprocess.call(p[i]) 
File "C:\Portable Python 2.7.3.1\App\lib\subprocess.py", line 493, in call 
return Popen(*popenargs, **kwargs).wait() 
File "C:\Portable Python 2.7.3.1\App\lib\subprocess.py", line 679, in __init__ 
errread, errwrite) 
File "C:\Portable Python 2.7.3.1\App\lib\subprocess.py", line 896, in _execute_child 
startupinfo) 
WindowsError: [Error 2] The system cannot find the file specified 

回答

0

我建议使用一个单独的线程的工作启动。最简单的方法是使用thread模块中的start_new_thread方法。

更改提交按钮的命令command=lambda:thread.start_new_thread(ext_process,())

你可能会想它的点击时禁用按钮,使它发射完成时。这可以在ext_process内完成。

如果您想允许用户取消作业,它会变得更加复杂。这个解决方案不会处理。

+0

谢谢@Tim。我编辑了这篇文章。 – Shreyas

+0

@Shreyas:没问题。还有什么你需要回答吗?如果不是,并且您对此答案感到满意,请[接受它](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)。 – Tim

+0

:我刚刚注意到,一旦过程完成,GUI程序就会挂起! – Shreyas

相关问题