2017-01-04 41 views
1

运行服务器,我做的是创建一个单独的Python的Web服务器,该服务器的计划书后:的Tkinter窗口冻结从脚本

import os, sys 
from http.server import HTTPServer, CGIHTTPRequestHandler 

webdir = '.' 
port = 8000 
print('Server Now Running') 
os.chdir(webdir) 
srvraddr = (('' , port)) 
srvrobj = HTTPServer(srvraddr, CGIHTTPRequestHandler) 
srvrobj.serve_forever() 

,然后原来的程序运行由命令行服务器:

def runServer(self): 
    os.system('Webserver.py') 

所有这些都是通过Tkinter窗口中的按钮完成的。当这个函数被调用时,Tkinter窗口会冻结,并且不能按下下一个按钮(一个会在Safari中通过服务器拉起本地html文件)。

我环顾四周,它看起来像我可能需要线程或东西...

我已经离开了我一无所知,我怎么会去这一点。如果有必要,可以提供更多我的原始程序(这有点笨拙)。

我正在寻找一个简单的解决方案或可能是一个具体的参考,让我朝着正确的方向前进。

Python非常新(3个月),所以请记住这一点。

+2

当你运行'os.system'时,它会等到它结束。这种'mainloop'不能完成它的工作 - 接收键/鼠标事件,发送到窗口小部件,重绘窗口小部件等。你需要模块'threading'或'subprocess'作为单独的线程/进程运行服务器,然后'mainloop '会做好自己的工作。 – furas

+0

现在就研究这个......你能给我一个这个程序中看起来像什么的概念吗? – peer

+0

[线程](https://docs.python.org/3.5/library/threading.html)和[subprocess](https://docs.python.org/3.5/library/subprocess.html) – furas

回答

2

使用subprocess

import subprocess 

s = subprocess.Popen(['Webserver.py']) 

也许它需要python启动脚本

s = subprocess.Popen(['python', 'Webserver.py']) 

,或者你可以运行

s = subprocess.Popen(['python3', '-m', 'http.server', '--cgi', '8000']) 

,以后你可以停止过程

s.kill() 

  • Popen(无参数shell=True)预计参数作为列表
  • 后您关闭程序子仍然有效,所以你必须在您关闭计划要杀死他们。
+0

完全合作!这非常简单。这里是我的新功能:def runServer(self): \t \t nm = self.e2。get() \t \t fld =“/ Users/peer/temp /”+ self.e1.get()+“/”+ nm +“.py” \t \t s = subprocess.Popen(['python3', FLD])。 e2是Web服务器文件的名称,e1是创建的顶层文件夹。谢谢很多 – peer

+0

我现在想看看我应该把s.kill()放在哪里。记得我在Tkinter窗口中...我需要保持服务器运行,直到程序关闭。 – peer

+1

你可以在'mainloop()'之后放's.kill()' - 它会在关闭窗口后执行。或者,如果你有按钮关闭窗口,然后分配's.kill()'和'window.destroy()'的函数 – furas

1

由于被调用程序的退出代码是函数os.system的返回值,程序将被阻止,直到被调用程序退出。

尝试使用非阻塞subprocess.Popen来代替。

+0

因此,p = self.runServer,subprocess.Popen(p)???我迷路了。现在阅读线程的基本知识。一个例子是非常宝贵的。 – peer