PDA

View Full Version : Regarding qt real time plot using qml wrapper for Qcustomplot



user03
26th August 2016, 18:15
I am using the following wrapper: https://github.com/ncp1402/ql-lineplot to plot the data in real-time, I could plot the data in a static manner (not real time) however, on trying the below code (relevant for realtime), my application crashes (no error message)


import QtQuick 2.0

import 'src/qml'
import QtQuick.Layouts 1.2
QlLinePlot { id:plot; Layout.fillWidth:true; Layout.fillHeight:true;

// X/Y labels
labelX: 'time'
labelY: 'Values'

// show legend
legend: true

// enable/disable autorange
autoRange: true

// enable/disable X/Y mouse drag
dragX: true
dragY: true

// enable/disable X/Y mouse zoom (with Shift - only X, with Ctrl - only Y)
zoomX: true
zoomY: true

// enable/disable time/date format for X axis
xDate: true
// time/date format
xDateFormat: 'hh.mm.ss'
yPrev:[4,2,3]

property var colors: ['red']
property var names: ['T1']
Timer{
id:textTimer
interval:1000
repeat:true
running:true
triggeredOnStart: true
// initialize plot
Component.onCompleted: {
// remove all graphs
//clearGraphs();
// add new graphs
for (var i=0; i <= colors.length; i++)
addGraph(names[i], true, colors[i], 3, 'solid');

var i1=0;
while(adcreader.hasSample()) //check whether a sample is present or not
{

plot.addPoints(i1, [adcreader.getSample()]); //get it and plot
i1++;
}
plot.visible= true;

}
}

}

I think there is some mistake in the way I have tried to plot, since, I don't have experience of using Qt, any suggestions regarding the changes required will be great!

anda_skoa
26th August 2016, 18:27
How does that even load?
The import for QlLinePlot is missing.

It also doesn't have any size unless it has some implicit size or is put into a layout at the place this is instantiated from.

Also the timer seems to be useless as its triggered signal is not handled.

Cheers,
_

user03
26th August 2016, 20:05
How does that even load?
The import for QlLinePlot is missing.
_
It also doesn't have any size unless it has some implicit size or is put into a layout at the place this is instantiated from.

Also the timer seems to be useless as its triggered signal is not handled.

Cheers,


That is import 'qml' and I could plot the data properly without running it in real time. Could you suggest an appropriate way to get it done in real time?

anda_skoa
27th August 2016, 10:45
That is import 'qml' and I could plot the data properly without running it in real time.

I see.
I mistook the Q1LinePlot with the Q1LinePlotItem that is registered in C++. I guess this is used inside th Q1LinePlot.qml



Could you suggest an appropriate way to get it done in real time?
Your data source needs to notify the QML side then it has new data, and then you need to update the plot.

Cheers,
_

user03
27th August 2016, 10:59
Okay, I have defined two slots called hasSample and getSample, hasSample when queried returns true/false (boolean) and getSample returns the value to be plotted (int). Below are the two functions


int Classname::getSample()
{
int ret= buff[outp];
outp=(outp+1)%100;
return ret;
}
//return size
bool Classname::hasSample() const
{
if(inp==outp)
return false;
else
return true;
}

//statements from another function in .cpp that gets the value:
buff[inp]=foo; //value added in the buffer
inp=(inp+1)%100;

Kkindly correct me if this not the proper way to get it done. Also, I found this link: http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html . May be I need to access the QQmlProperty? Thank you.

anda_skoa
27th August 2016, 13:09
Okay, I have defined two slots called hasSample and getSample, hasSample when queried returns true/false (boolean) and getSample returns the value to be plotted (int). Below are the two functions

Yes, these look ok and you already said they work.

As I said in my last comment, you need to notify the QML side about new data.
So add a signal and emit it when new data arrives.

Then you react to that signal in QML, e.g. by connecting a function to it or by using a Connections element.

In both cases I would recommend to move the code that clears and fills the plot into a function.
Then it can be called from onCompleted and the signal handler.



Also, I found this link: http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html . May be I need to access the QQmlProperty? Thank you.
No, this has nothing to do with what you need here.

Cheers,
_

user03
28th August 2016, 17:02
I could finally get the signal part in .cpp done but I am still not sure on how to make qml read the changed signal value every time, I could get a static plot but how can I make sure that every signal emitted event gets a response in qml plot.
I tried below code in qml:
Component.onCompleted: {
var i1=0;
while(1)
{
plot.addPoints(i1, [adcreader.t]); //integer t is the updated value
i1++;
}
}

However, the application crashes each time (due to while loop but I don't know how else can I make it to constantly check the updated value)

anda_skoa
28th August 2016, 21:02
1) in QML add a function to the QlLinePlot item.
2) in that function clear all points and call your addPoints loop
3) verify that everything works when you call that function from Component.onCompleted.

Then add this to the Component.onCompleted


adcreader.yourSignalName.connect(yourFunctionName) ;


Cheers,
_

user03
28th August 2016, 21:05
Okay, thanks for the help, I'll try these things now, however,



Then you react to that signal in QML, e.g. by connecting a function to it or by using a Connections element.
_


Could you please tell me if you are referring to something of this sort:
Q_PROPERTY(int t READ ai NOTIFY aiChanged)

and this aiChanged signal should be emitted by the method which gets the updated value? I am totally confused about this signal and slot concept

anda_skoa
29th August 2016, 09:55
Could you please tell me if you are referring to something of this sort:
Q_PROPERTY(int t READ ai NOTIFY aiChanged)

and this aiChanged signal should be emitted by the method which gets the updated value? I am totally confused about this signal and slot concept
Not quite.

You don't need a property if you keep using your "hasSamples" and "getSample" methods, just the signal to notify the QML side that it has to call these again.

But the signal declaration is bascially equal to how you would declare the aiChanged signal and you emit it the same way as the uiChanged signal.

Cheers,
_