问题描述
我使用Python 3.7和Qt5制作了一个UI。
有一个按钮可以启动本地http.server并打开一个页面以显示一些报告数据。
问题是当我单击按钮时,它运行我的脚本,启动服务器并正确打开页面,但我的用户界面被阻止。就像在ui再次工作之前等待服务器完成其工作一样。
我读到ui Tq不好用多线程。是否有任何技巧可以独立于我的用户界面打开http.server?
该方法由按钮运行时的代码:
def OpenReport():
class ReportHTTPHandler (http.server.SimpleHTTPRequestHandler):
def run_cgi(self,reportclass):
# Setup environment variables -
_,_,query = self.path.partition ('?')
os.environ['QUERY_STRING'] = query
# Cookies
co = filter (None,self.headers.get_all ('cookie',[]))
cookie_str = ','.join (co)
if cookie_str:
os.environ['HTTP_COOKIE'] = cookie_str
cgitb.enable ()
f = io.StringIO ()
with redirect_stdout (f):
reportclass.runCGI (self)
output = f.getvalue ()
self.send_response (HTTPStatus.OK,'')
self.flush_headers ()
self.wfile.write (''.join (output).encode ())
self.wfile.flush ()
return
def send_head(self):
# Split the query string for parsing later
path,query = self.path.partition ('?')
# Check if URL is a report
# This is not the neatest way
if path == '/cgi/index.py':
return ReportHTTPHandler.run_cgi (self,ReportIndex)
elif path == '/cgi/facebook.py':
return ReportHTTPHandler.run_cgi (self,ReportFacebook)
elif path == '/cgi/google-map.py':
return ReportHTTPHandler.run_cgi (self,ReportGoogleMap)
elif path == '/cgi/instagram.py':
return ReportHTTPHandler.run_cgi (self,ReportInstagram)
elif path == '/cgi/linkedin.py':
return ReportHTTPHandler.run_cgi (self,ReportLinkedIn)
elif path == '/cgi/sms.py':
return ReportHTTPHandler.run_cgi (self,ReportSMS)
elif path == '/cgi/telegram.py':
return ReportHTTPHandler.run_cgi (self,ReportTelegram)
elif path == '/cgi/twitter.py':
return ReportHTTPHandler.run_cgi (self,ReportTwitter)
else:
# Assume this is an asset
return http.server.SimpleHTTPRequestHandler.send_head (self)
port = 50000
address = ("",port)
server = http.server.HTTPServer
handler = ReportHTTPHandler
httpd = server (address,handler)
print (f"Report tool server started on port {port}")
webbrowser.open (f'http://localhost:{port}/cgi/index.py',new=2)
try:
httpd.serve_forever ()
except KeyboardInterrupt:
print ("\nKeyboard interrupt received,exiting.")
sys.exit (0)
加载ui并运行服务器的代码:
# === Load the UI =========================================
gui = QtWidgets.QApplication([])
ui = uic.loadUi('ui/MyUI.ui')
ui.button_Report.clicked.connect(OpenReport)
ui.show()
gui.exec()
解决方法
点击按钮后,您可以在线程中启动服务器,并将状态发送回用户界面
<div><div>Hello</div></div>