在我的Python Dash应用程序中,我想显示一些PyQt5窗口弹出窗口。这些是从回调内部激活的。
不幸的是,当显示弹出窗口时,我在控制台中收到此警告:
警告:未在main()线程中创建QApplication。
我的问题:如果从Python Dash回调内部调用它,如何在main()线程中创建QApplication?
在下面,您可以找到代表mwe的代码。如果运行此代码段,则会看到警告。显然,当从回调内激活QApplication时,它不在主线程上运行(我猜是app.run_server()已在主线程上运行)。我如何修改它,以便QApplication位于主线程中?
该示例类似于PyQt5 GUI中的Use Dash(plot.ly),但不相同(我希望Dash中的pyqt5,而不是pyqt5中的Dash)。
import os, dash
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtCore import QCoreApplication
import dash_html_components as html
from dash.dependencies import Input, Output
class MainWindow(QMainWindow):
#some Qpop up
pass
app = dash.Dash()
app.layout = html.Div(children=[
html.H1(children='Hello Dash'),
#button which, if pressed, created a QApplication in a non-main thread
html.Button("show pop up", id="button"),
html.H2(children='', id='result')
])
#The callback which creates the pop up I want to show.
#This is activated when the button "show pop up" is pressed, and causes the warning to appear
@app.callback(
Output(component_id='result', component_property='children'),
[Input(component_id='button', component_property='n_clicks')]
)
def popUp(n_clicks):
if not n_clicks:
raise dash.exceptions.PreventUpdate
app = QCoreApplication.instance()
if app is None:
app = QApplication([os.getcwd()])
mainWin = MainWindow()
mainWin.show()
app.exec_()
return "You saw a pop-up"
if __name__ == '__main__':
app.run_server(debug=False)
问题来源:stackoverflow
逻辑是在辅助线程中运行Dash并通过如下所示的信号将通知发送到GUI(此答案基于我的其他答案):
import functools
import os
import threading
from PyQt5 import QtCore, QtWidgets
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
class MainWindow(QtWidgets.QMainWindow):
closed = QtCore.pyqtSignal()
def closeEvent(self, event):
self.closed.emit()
super().closeEvent(event)
class Manager(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._view = None
@property
def view(self):
return self._view
def init_gui(self):
self._view = MainWindow()
@QtCore.pyqtSlot()
def show_popup(self):
if self.view is not None:
self.view.show()
qt_manager = Manager()
app = dash.Dash()
app.layout = html.Div(
children=[
html.H1(children="Hello Dash"),
html.Button("show pop up", id="button"),
html.H2(children="", id="result"),
]
)
@app.callback(
Output(component_id="result", component_property="children"),
[Input(component_id="button", component_property="n_clicks")],
)
def popUp(n_clicks):
if not n_clicks:
raise dash.exceptions.PreventUpdate
loop = QtCore.QEventLoop()
qt_manager.view.closed.connect(loop.quit)
QtCore.QMetaObject.invokeMethod(
qt_manager, "show_popup", QtCore.Qt.QueuedConnection
)
loop.exec_()
return "You saw a pop-up"
def main():
qt_app = QtWidgets.QApplication.instance()
if qt_app is None:
qt_app = QtWidgets.QApplication([os.getcwd()])
qt_app.setQuitOnLastWindowClosed(False)
qt_manager.init_gui()
threading.Thread(
target=app.run_server, kwargs=dict(debug=False), daemon=True,
).start()
return qt_app.exec_()
if __name__ == "__main__":
main()
回答来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。