Reputation: 1193
I made a UI with Python 3.7 and Qt5.
There is a button which launch a local http.server and open a page to show some report data.
The problem is when I click on button, it run my script, launch the server and open the page correctly but my ui is blocked. It is like waiting the server finish its job before ui works again.
I’ve read multithreading is not good with ui Tq. Is there any trick to open the http.server independently from my ui?
Code if the method run by the button:
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)
Code which load the ui and run the server:
# === Load the UI =========================================
gui = QtWidgets.QApplication([])
ui = uic.loadUi('ui/MyUI.ui')
ui.button_Report.clicked.connect(OpenReport)
ui.show()
gui.exec()
Upvotes: 0
Views: 400
Reputation: 684
You can launch your server in thread when button click and signal the status back to your UI
def buttonClick(self):
t = threading.Thread(target=self.startServer)
t.start()
def startServer(self):
*Launch Server
self.progress_signal.emit("Complete")
Upvotes: 1