【发布时间】:2020-08-12 14:33:50
【问题描述】:
我正在开发一个 Python 项目,其中包括基于 pyqt5 和 flask 的 API。在 UI 中,有start 和stop 按钮,按下它们将启动flask api 服务器并在单击停止按钮时停止。
from server import start_local_server
from multiprocessing import Process
"""
SOME CODE
"""
def start_server_btn_event(self):
p1 = Process(target=start_local_server())
p1.start()
def stop_server_btn_event(self):
# Code to stop the api server
但上述操作会使整个 UI 无响应,我无法单击 UI 上的任何其他对象。如何在单独的线程或进程中单击按钮时运行 api 服务器,以便其他 UI 对象处于活动状态并可以执行其功能。谢谢
最小可重现示例:
app.py : 这包含启动本地服务器的 pyqt5 按钮
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from server import start_local_server
from PyQt5.QtCore import pyqtSlot
from multiprocessing import Process
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
start_btn = QPushButton('Start Server', self)
start_btn.move(100, 70)
start_btn.clicked.connect(self.on_click_start_btn)
stop_btn = QPushButton('Stop Server', self)
stop_btn.move(200, 70)
stop_btn.clicked.connect(self.on_click_stop_btn)
fun_btn = QPushButton('Click to check responsiveness', self)
fun_btn.move(150, 100)
fun_btn.clicked.connect(self.on_click_fun_btn)
self.show()
@pyqtSlot()
def on_click_start_btn(self):
# Start server here
p1 = Process(target=start_local_server())
p1.start()
@pyqtSlot()
def on_click_stop_btn(self):
print("Stop server ")
@pyqtSlot()
def on_click_fun_btn(self):
print('If it is working, this means UI is responsive')
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
server.py:这是flask api服务器代码
import os
import datetime
from flask import Flask, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
wsgi_app = app.wsgi_app
@app.route('/api/status')
def check_status():
return jsonify({'status': 'ok', 'date': datetime.datetime.now().isoformat()}), 200
def start_local_server():
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, 80)
【问题讨论】:
-
正如文档所说:“[join] 方法会阻塞,直到进程 [...] 终止”。在主 Qt 线程中不应该发生任何阻塞功能。为什么叫它?
-
@musicamante 对不起,我对
join有不同的理解。我已将其删除,但 UI 仍然无响应 -
@musicamante 我已经用最少的可重现示例更新了代码。请看一看。谢谢
-
@SAndrew Typo:将
p1 = Process(target=start_local_server())更改为p1 = Process(target=start_local_server)
标签: python multithreading flask process pyqt5