Как открыть веб окно по кнопке в pyqt?
Хочу открыть web окно с изображением графика plotly по кнопке. Пытаюсь открыть, но либо web окно открывается на долю секунды, либо всё закрывается без ошибки.
import plotly.offline as po
import plotly.graph_objs as go
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWebEngineWidgets import QWebEngineView
import sys
def start_web(fig):
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
fig_view = QWebEngineView()
screen = app.primaryScreen()
size = screen.size()
fig_view.resize(size.width() / 2, size.height() / 2)
fig_view.setHtml(raw_html)
fig_view.show()
fig_view.raise_()
return fig_view
def on_clicked():
fig = go.Figure(data=[{'type': 'scattergl', 'y': [2, 1, 3, 1, 10]}])
fig_view = start_web(fig)
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setWindowTitle("График температуры")
screen = app.primaryScreen()
size = screen.size()
window.resize(size.width() / 4, size.height() / 4)
text_com_ports = QtWidgets.QLabel("Com-порт", window)
text_addr_slave = QtWidgets.QLabel("Адресс устройства", window)
text_addr_regs = QtWidgets.QLabel("Регистр", window)
btn_connect = QtWidgets.QPushButton("Подключиться", window)
btn_connect.resize(280, 60)
btn_trend = QtWidgets.QPushButton("Открыть график", window)
text_com_ports.setGeometry(10, 10, 100, 100)
com_ports = QtWidgets.QComboBox(window)
com_ports.move(250, 10)
for i in range(0, 21):
com_ports.addItem(str(i))
addr_slave = QtWidgets.QSpinBox(window)
addr_regs = QtWidgets.QSpinBox(window)
addr_slave.move(350, 10)
addr_slave.setMaximum(256)
addr_regs.move(500, 10)
addr_regs.setMaximum(256)
grid = QtWidgets.QGridLayout(window)
grid.addWidget(text_com_ports, 0, 0)
grid.addWidget(com_ports, 0, 1)
grid.addWidget(text_addr_slave, 1, 0)
grid.addWidget(addr_slave, 1, 1)
grid.addWidget(text_addr_regs, 2, 0)
grid.addWidget(addr_regs, 2, 1)
grid.addWidget(btn_connect, 3, 0)
grid.addWidget(btn_trend, 3, 1)
btn_trend.clicked.connect(on_clicked)
window.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Получается, что fig_view это локальная переменная,
которая удаляется сборщиком мусора.
Попробуйте так:
import sys
import plotly.offline as po
import plotly.graph_objs as go
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWebEngineWidgets import QWebEngineView
class Widget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("График температуры")
screen = app.primaryScreen()
size = screen.size()
self.resize(size.width() / 4, size.height() / 4)
self.browser = None
text_com_ports = QtWidgets.QLabel("Com-порт")
text_addr_slave = QtWidgets.QLabel("Адресс устройства")
text_addr_regs = QtWidgets.QLabel("Регистр")
btn_connect = QtWidgets.QPushButton("Подключиться")
btn_trend = QtWidgets.QPushButton("Открыть график")
btn_trend.clicked.connect(self.on_clicked)
com_ports = QtWidgets.QComboBox()
com_ports.addItems([ str(i) for i in range(21)])
addr_slave = QtWidgets.QSpinBox(maximum=256)
addr_regs = QtWidgets.QSpinBox(maximum=256)
grid = QtWidgets.QGridLayout(self)
grid.addWidget(text_com_ports, 0, 0)
grid.addWidget(com_ports, 0, 1)
grid.addWidget(text_addr_slave, 1, 0)
grid.addWidget(addr_slave, 1, 1)
grid.addWidget(text_addr_regs, 2, 0)
grid.addWidget(addr_regs, 2, 1)
grid.addWidget(btn_connect, 3, 0)
grid.addWidget(btn_trend, 3, 1)
@QtCore.pyqtSlot()
def start_web(self, fig):
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
return raw_html
@QtCore.pyqtSlot()
def on_clicked(self):
self.browser = QWebEngineView()
fig = go.Figure(data=[{'type': 'scattergl', 'y': [2, 1, 3, 1, 10]}])
fig_view = self.start_web(fig)
self.browser.setHtml(fig_view)
self.browser.show()
def closeEvent(self, event):
if self.browser:
self.browser.hide()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
view = Widget()
view.show()
sys.exit(app.exec_())
