Reputation: 329
I want to plot data in Qt charts (QML) from python. The x,y data are saved in array x = np.array([0, 6]) y = np.array([0, 250])
. I am desperate how to pass these data to Qt Charts with one step. I can do it (step by step) with Signal/Slot, where the Signal is with parameters (x,y).
My working (very slow) code:
Creating signal from python to qml:
class AppWindow(QObject):
# Signals from python to QML
sigPlotData = Signal(int, int, arguments=['x','y'])
and later () I generate and send data to chart like that:
...
for i in range(50):
self.app.sigPlotData.emit(i, random.randint(0,150))
...
In QML file I do this:
//connections from Python to QML via signals
Connections {
target: backend
function onSigPlotData(x,y){
lineSer.append(x, y);
}
}
ChartView {
id: chartView
title: "Line"
anchors.fill: parent
ValueAxis{
id: axisX
min: 0
max: maxX
}
ValueAxis{
id: axisY
min: 0
max: 150
}
LineSeries {
id: lineSer
name: "data"
axisX: axisX
axisY: axisY
}
}
Thank you very much for help.
Upvotes: 1
Views: 2467
Reputation: 329
For me the best solution:
start = time.time()
points = []
for i in self.x:
points.append(QPointF(i, self.y[i])) # filling points with my prepared data
serie1.replace(points) # fill list of points in one call
end = time.time()
print(end - start)
for 50000 values it takes only 126 ms, for 5000 values it takes 13 ms
Upvotes: 0
Reputation: 3893
you can have this :
in main.py :
import os
from pathlib import Path
import sys
from PyQt5.QtCore import QCoreApplication, Qt, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
def main():
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(
handle_object_created, Qt.ConnectionType.QueuedConnection
)
engine.load(url)
sys.exit(app.exec())
if __name__ == "__main__":
main()
and in main.qml
:
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtCharts 2.15
ApplicationWindow {
visible: true
width: 600
height: 300
property int timeStep: 0
ChartView {
id: chartView
anchors.fill: parent
ValueAxis {
id: axisX
min: 0
max: 400
}
LineSeries {
id: series1
axisX: axisX
name: "data"
}
}
Timer {
interval: 100
repeat: true
running: true
onTriggered: {
timeStep++;
var y = (1+Math.cos(timeStep/10.0))/2.0;
series1.append(timeStep, y);
}
}
}
Result is:
In QML you can create your function or other things like(for, if,..) with javascript syntax
and as you see I use series1.append(timeStep, y);
means append function for adding data.
Upvotes: 2