在pyqt5中动态更改数据破折号
Posted
技术标签:
【中文标题】在pyqt5中动态更改数据破折号【英文标题】:change dynamically data dash in pyqt5 【发布时间】:2020-07-27 12:37:04 【问题描述】:所以我制作了一个应用程序,它在 pyqt5 中显示虚线图,它从表格小部件中获取数据。应用程序在第一个数据上表现良好,但如果我更改表中的数据,我也无法在图表中看到变化,那么问题出在哪里?
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import dash
import dash_core_components as dcc
import dash_html_components as html
import threading
import plotly.figure_factory as ff
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(956, 701)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.centralwidget)
self.webEngineView.setUrl(QtCore.QUrl("http://127.0.0.1:8050"))
self.webEngineView.setObjectName("webEngineView")
self.verticalLayout.addWidget(self.webEngineView)
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.verticalLayout.addWidget(self.tableWidget)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 956, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.tableWidget.setColumnCount(3)
self.tableWidget.setRowCount(3)
self.tableWidget.setHorizontalHeaderLabels(('X', 'Y1','Y2'))
header = self.tableWidget.horizontalHeader()
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
self.pushButton.clicked.connect(self.Clicked)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def Clicked(self):
df=[]
data = []
for c in range(self.tableWidget.columnCount()):
data.append([])
for r in range(self.tableWidget.rowCount()):
data[c].append(self.tableWidget.item(r,c).text())
for r in range(self.tableWidget.rowCount()):
df.append(dict(Task=data[0][r], Start=data[1][r], Finish=data[2][r]))
print(df)
threading.Thread(target=self.run_dash, args=([df]), daemon=True).start()
def run_dash(self,df):
fig = ff.create_gantt(df)
app = dash.Dash()
app.layout = html.Div([
dcc.Graph(figure=fig)
])
app.run_server(debug=True, use_reloader=False)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
from PyQt5 import QtWebEngineWidgets
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
Optimizer = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(Optimizer)
Optimizer.show()
sys.exit(app.exec_())
注意:第二列和第三列是显示甘特图的日期列。所以这两列中的数据输入应该是:2020-07-27 | 2020-07-30
【问题讨论】:
【参考方案1】:Dash 启动一个更新信息的服务器,但这是由浏览器呈现的,这意味着尽管服务器在客户端更新了信息,但它必须请求更新的信息并重新绘制它。这可以通过重新加载页面来完成:
import sys
import threading
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.figure_factory as ff
class QDash(QtCore.QObject):
def __init__(self, parent=None):
super().__init__(parent)
self._app = dash.Dash()
self.app.layout = html.Div()
@property
def app(self):
return self._app
def update_graph(self, df):
fig = ff.create_gantt(df)
self.app.layout = html.Div([dcc.Graph(figure=fig)])
def run(self, **kwargs):
threading.Thread(target=self.app.run_server, kwargs=kwargs, daemon=True).start()
class Mainwindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.browser = QtWebEngineWidgets.QWebEngineView()
self.table = QtWidgets.QTableWidget()
self.button = QtWidgets.QPushButton("Press me")
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self.browser, stretch=1)
lay.addWidget(self.table, stretch=1)
lay.addWidget(self.button)
self.resize(640, 480)
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(("X", "Y1", "Y2"))
header = self.table.horizontalHeader()
for i in range(self.table.columnCount()):
header.setSectionResizeMode(i, QtWidgets.QHeaderView.Stretch)
self.qdask = QDash()
self.qdask.run(debug=True, use_reloader=False)
self.browser.load(QtCore.QUrl("http://127.0.0.1:8050"))
self.button.clicked.connect(self.update_figure)
current_date = QtCore.QDateTime.currentDateTime()
for i in range(3):
self.append_row(
task="Task".format(i),
start=current_date,
finish=current_date.addDays(i + 1),
)
@QtCore.pyqtSlot()
def update_figure(self):
df = []
for i in range(self.table.rowCount()):
task = self.table.item(i, 0).data(QtCore.Qt.DisplayRole)
start = (
self.table.item(i, 1)
.data(QtCore.Qt.DisplayRole)
.toString(QtCore.Qt.ISODateWithMs)
)
finish = (
self.table.item(i, 2)
.data(QtCore.Qt.DisplayRole)
.toString(QtCore.Qt.ISODateWithMs)
)
d = dict(Task=task, Start=start, Finish=finish)
df.append(d)
print(df)
self.qdask.update_graph(df)
self.browser.reload()
def append_row(
self,
task="",
start=QtCore.QDateTime.currentDateTime(),
finish=QtCore.QDateTime.currentDateTime(),
):
row = self.table.rowCount()
self.table.insertRow(row)
for column, value in enumerate((task, start, finish)):
it = QtWidgets.QTableWidgetItem()
it.setData(QtCore.Qt.DisplayRole, value)
self.table.setItem(row, column, it)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
w = Mainwindow()
w.show()
sys.exit(app.exec_())
【讨论】:
以上是关于在pyqt5中动态更改数据破折号的主要内容,如果未能解决你的问题,请参考以下文章