PDA

View Full Version : display a plot point by point



oswalidos
9th March 2009, 16:46
hello :)
i finally downloaded qwt from svn and everything is ok (Qt 4.5 ,qwt 5.3.0,windows xp)
now i need to display a plot point by point ,so i tried to create a retard with Qtimer ,but it doesn't work !

no execution or complilation errors but i haven't the result i'm expecting
it's my first program with qwt ,i'm following the pdf given with qwt 5.1.1
the documentation for qwt 5.1.1 still useful ?

thanks in advance :)

oswalidos
9th March 2009, 19:57
maybe i'm not clear :(
i simply want to see plot painting point by point because i'm working on a "real-time" application ,points will be available while my system is running ,so i plan to use Qthread to synchronize tasks .
now i need to know how can i control displaying plots ?
can i find signals or create signals to do such thing ?
thanks for your help :)

wysota
9th March 2009, 22:15
Can we see the code?

oswalidos
9th March 2009, 22:24
i just tried a code which stored data first ,after it display the curve



#include <QtGui>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_legend.h>
#include <qwt_series_data.h>
#include <qwt_text.h>
#include <math.h>

class Plot : public QwtPlot
{
public:
Plot();
};

Plot::Plot()
{
double x[100];
double y1[100];
double y2[100];

for(int i=0;i<100;i++){
x[i]=i;
y1[i]=i*i;
y2[i]=i;
}


setTitle("Vitesse et angle de braquage en fonction du temps");
insertLegend(new QwtLegend(), QwtPlot::RightLegend);

// Set axes
setAxisTitle(xBottom, "Temps");
setAxisScale(xBottom, 0.0, 100);

setAxisTitle(yLeft, "");
setAxisScale(yLeft, 0.0, 100);

// add curves
QwtPlotCurve *curve1 = new QwtPlotCurve("Vitesse");
curve1->setPen(QPen(Qt::green));
curve1->attach(this);
curve1->setData(x, y1, 100);

QwtPlotCurve *curve2 = new QwtPlotCurve("Angle de Braquage");
curve2->setPen(QPen(Qt::red));
curve2->attach(this);
curve2->setData(x, y2, 100);

// ...a horizontal line ...
QwtPlotMarker *mY = new QwtPlotMarker();
mY->setLabel(QString::fromLatin1("t ( ms )"));
mY->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
mY->setLineStyle(QwtPlotMarker::HLine);
mY->attach(this);

// ...a vertical line ...
QwtPlotMarker *mX = new QwtPlotMarker();
mX->setLabel(QString::fromLatin1("V ( m/s ) ,Ang ( rad/s )"));
mX->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
mX->setLineStyle(QwtPlotMarker::VLine);
mX->attach(this);

}


int main(int argc, char **argv)
{
QApplication a(argc, argv);

Plot *myPlot = new Plot();
myPlot->autoRefresh();

myPlot->resize(600,400);
myPlot->show();

return a.exec();
}



i want to change this code to display the curve step by step from (0,0) until (n,m) while time progressing !

wysota
9th March 2009, 22:42
So where is your timer code?

oswalidos
9th March 2009, 22:46
i don't know where should i put timer .
i'm asking how can i put timer ?
i may should use other classes not Qwtplot cuz it needs the data stored to display curves .
i tried with timer somewhere but it doesn't seem to work !
i think i have to use others classes or some signals to control painting process .

wysota
9th March 2009, 22:51
You should start a timer somewhere in your code and connect its timeout() signal to a custom slot that you have to implement. Inside the slot simply add more data to the curves.

oswalidos
9th March 2009, 23:17
all data is fixed in constructor and can't be anywhere else .
i think constructor can't be dynamic ,it's fixed since we instance an object from its class .
if constructor still running when application is running that's mean is using more than thread ,that's can be right ?
can i call constructor many times to change object's value and display it using timer ? i don't think so !

wysota
9th March 2009, 23:33
In the constructor you can store the data in some array. Then you can add the data to the plot in some other place (like a slot).

oswalidos
10th March 2009, 00:10
thanks for your help ,
i'll try but logically data in constructor should be given only one time .

wysota
10th March 2009, 00:29
I think you don't understand me. You can keep the data in two places - one of them is initialized and filled with data in the constructor. The other is the plot itself that is fed with the data from the first container using a timer.

Here is a skeleton of a code doing what I mean:

X::X(){
for(int i=0;i<100;i++){
x[i]=i;
y1[i]=i*i;
y2[i]=i;
}
curve1 = new QwtPlotCurve("Vitesse"); // curve1 is a member variable
currentPointPosition = 1; // currentPointPosition is a member variable
updateData();
QTimer *timer = new QTimer(...);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
timer->start(500);
//...
}

void X::onTimeout(){
currentPointPosition++;
if(currentPointPosition>100) currentPointPosition = 1;
updateData();
}

void X::updateData(){
curve1->setData(x, y1, currentPointPosition);
}

oswalidos
10th March 2009, 21:24
hello ,
thanks for the skeleton,i'm trying to apply your idea but i get blocked is something .
when i define the macro Q_OBJECT an error appear :

undefined refrence to vtabe for plot

my .pro is :


TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += C:\svn\qwt\qwt\src
LIBS += C:\svn\qwt\qwt\lib\qwtd5.dll
CONFIG += debug

# Input
SOURCES += main.cpp


main.cpp :

class Plot : public QwtPlot
{
//Q_OBJECT
public:
Plot();
void pointByPoint();

private :
QwtPlotCurve *curve1;
int currentPointPosition;
QTimer *timer;
double *x;
double *y;

/*
public slots:
void onTimeout(); */
};


Plot::Plot()
{
x=new double[100];
y=new double[100];

for(int i=0;i<100;i++){
x[i]=i;
y[i]=i*i;
}

//......

timer = new QTimer();
//connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));

}

/*
void Plot::onTimeout(){ //each timeout data will
currentPointPosition++; // be added to the curve
if(currentPointPosition>100) currentPointPosition = 1;
curve1->setData(x, y1, currentPointPosition);
}
*/

void Plot::pointByPoint(){ //calling this method provoque painting curve "slowly"
while(true){
timer->start(500);
}
}


int main(int argc, char **argv)
{
QApplication a(argc, argv);

Plot *myPlot = new Plot();
myPlot->autoRefresh();
myPlot->resize(600,400);
myPlot->show();

//myPlot->pointByPoint();

return a.exec();
}


thanks for your help :)

wysota
10th March 2009, 21:34
Did you remember to run qmake after you added the macro?

oswalidos
10th March 2009, 21:48
ohhh ,sorry ,i'm working with Qt creator and i forgot about qmake !!
thanks a lot :)
it works first time but now :
this code still make error : undefined reference to "vtable for plot"


class Plot : public QwtPlot
{
Q_OBJECT
public:
Plot();
void pointByPoint();

private :
QwtPlotCurve *curve;
int currentPointPosition;
QTimer *timer;
double *x;
double *y;

public slots:
void onTimeout();
};


Plot::Plot()
{
x=new double[100];
y=new double[100];

for(int i=0;i<100;i++){
x[i]=i;
y[i]=i*i;
}

//........

timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}


void Plot::onTimeout(){ //each timeout data will
currentPointPosition++; // be added to the curve
if(currentPointPosition>100) currentPointPosition = 1;
curve->setData(x, y, currentPointPosition);
}


void Plot::pointByPoint(){ //calling this method provoque painting curve "slowly"
for(int i=0;i<200;i++){
timer->start(500);
}
}


int main(int argc, char **argv)
{
QApplication a(argc, argv);

Plot *myPlot = new Plot();
myPlot->autoRefresh();
myPlot->resize(600,400);
myPlot->show();

myPlot->pointByPoint();

return a.exec();
}


it's a shame to ask many questions but there is no documentation about qwt and i'm still beginner .
thanks for your help :)

wysota
10th March 2009, 22:01
Your issues are not related to Qwt. I'm even thinking about moving the thread to the newbie section of the board.

The Q_OBJECT macro has to be placed in a header file (with .h extension). It's possible to place it in an implementation file but it requires some additional work so let's try avoiding it for now. So if your class declaration is in an implementation (.cpp) file, move it to a header file, add the file to your project and rerun qmake and make.

oswalidos
10th March 2009, 22:32
ok, i did but macro problem persist like this :

D:/P2M/courbe/debug/courbe.exe exited with code 0
Starting D:/P2M/courbe/debug/courbe.exe...
D:/P2M/courbe/debug/courbe.exe exited with code -1073741819

if i make macro and slots as a comment everything seems work !

thx again :)

wysota
10th March 2009, 22:46
If your application crashes, it's not because of lack or presence of Q_OBJECT macro. Use a debugger to see where it crashes and why.

oswalidos
11th March 2009, 00:28
i don't know how to debug in console mode but i tried with qt creator .
when i run debug mode ,it still running with no information given ,debugger don't run until the first break point , it's written dbg running .

plot.h :


#include <QtGui>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_legend.h>
#include <qwt_series_data.h>
#include <qwt_text.h>
#include <math.h>


class Plot : public QwtPlot
{
Q_OBJECT
public:
Plot();
~Plot();
void pointByPoint();

private :
QwtPlotCurve *curve;
int currentPointPosition;
QTimer *timer;
double *x;
double *y;

public slots:
void onTimeout();
};



plot.cpp :


#include "plot.h"

Plot::Plot()
{
x=new double[100];
y=new double[100];

for(int i=0;i<100;i++){
x[i]=i;
y[i]=i*i;
}

currentPointPosition=1;

setTitle("Vitesse et angle de braquage en fonction du temps");
insertLegend(new QwtLegend(), QwtPlot::RightLegend);

// Set axes
setAxisTitle(xBottom, "Temps");
setAxisScale(xBottom, 0.0, 100);

setAxisTitle(yLeft, "");
setAxisScale(yLeft, 0.0, 100);

// add curves
curve = new QwtPlotCurve("Vitesse");
curve->setPen(QPen(Qt::green));
curve->attach(this);
curve->setData(x, y, currentPointPosition);

// ...a horizontal line ...
QwtPlotMarker *mY = new QwtPlotMarker();
mY->setLabel(QString::fromLatin1("t ( ms )"));
mY->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
mY->setLineStyle(QwtPlotMarker::HLine);
mY->attach(this);

// ...a vertical line ...
QwtPlotMarker *mX = new QwtPlotMarker();
mX->setLabel(QString::fromLatin1("V ( m/s ) ,Ang ( rad/s )"));
mX->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
mX->setLineStyle(QwtPlotMarker::VLine);
mX->attach(this);

timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}


void Plot::onTimeout(){ //each timeout data will
currentPointPosition++; // be added to the curve
if(currentPointPosition>100) currentPointPosition = 1;
curve->setData(x, y, currentPointPosition);
}


void Plot::pointByPoint(){ //calling this method provoque painting curve "slowly"
for(int i=0;i<200;i++){
timer->start(500);
}
}

Plot::~Plot(){
delete x;
delete y;
}



main.cpp


#include "plot.h"

int main(int argc, char **argv)
{
QApplication a(argc, argv);

Plot *myPlot = new Plot();
myPlot->autoRefresh();
myPlot->resize(600,400);
myPlot->show();

myPlot->pointByPoint();

return a.exec();
}


.pro :


TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += C:\svn\qwt\qwt\src
LIBS += C:\svn\qwt\qwt\lib\qwtd5.dll
CONFIG += debug

# Input
SOURCES += main.cpp \
plot.cpp
HEADERS += plot.h


i made as comment Q_OBJECT and my slot and it works ,i checked debugger too,it's ok with it under Qtcreator .

wysota
11th March 2009, 10:17
I'm sorry but I won't debug your code for you, you have to do that.

oswalidos
11th March 2009, 16:46
No , I'm sorry ,
i show the code cuz i suppose there is a simple mistake i can't see it as a Qt beginner .

wysota
11th March 2009, 17:34
I suggest you improve your C++ skills a bit before taking on Qt.

oswalidos
11th March 2009, 19:03
hello ,
i realized that my problem have no relation with my code.
in fact a simple application like "simple_plot" works normally when i create a new project ,move sources and modify *.pro ,but when i do the same for other example like "real_time plot" and try to build it , i have the same problem with a warning(exited with code -1073741819 ,no errors ,warning: #warning better use QwtData) and degugger don't works anymore .
so it's a configuration problem .
i downloaded qwt 5.2 from svn but it's the same problem !

-each time i want to run my application from Qt console or from Qt creator i have to add qwtd5.dll to debug folder,everybody do that ?
-i want to buid Qt in debug mode ,it takes time ,finally it generate errors related with visual studio 2008
-why to build Qt in debug mode?
-mingw's gdb isn't enough to debug Qt applications since we're using Qt's sources ?
-what about .pri and .prf ? should i modify one ?
-why debugger under Qt creator works(just for an application without macro Q_OBJECT) even if Qt isn't buit in debug mode ?

please look up my .pro
if my questions proves that i'm lost ,some links will be enough to stop annoying you .

regards

oswalidos
11th March 2009, 19:12
sorry ,my problem have no relation with c++ ,i didn't separate my files to .h and .cpp simply cuz i'm still testing qwt(that what makes you think i need to improve my c++ skills?) :o .
i'm sure my c++'s skills allows me to use Qt,it doesn't need a c++ expert !
anyway thanks for your help and advices .

oswalidos
11th March 2009, 19:18
my .pro for the real_time_plot :


TARGET = QDSQ
TEMPLATE = app
DEPENDPATH += .
INCLUDEPATH += C:\Qwt-5.2.0-svn\include
LIBS += C:\Qwt-5.2.0-svn\lib\qwtd5.dll
CONFIG +=debug

HEADERS += scrollzoomer.h \
scrollbar.h \
randomplot.h \
mainwindow.h \
incrementalplot.h
SOURCES += scrollzoomer.cpp \
scrollbar.cpp \
realtime.cpp \
randomplot.cpp \
mainwindow.cpp \
incrementalplot.cpp

OTHER_FILES += start.xpm \
clear.xp

wysota
11th March 2009, 21:24
-each time i want to run my application from Qt console or from Qt creator i have to add qwtd5.dll to debug folder,everybody do that ?
No, you can place the library in any place the dynamic linker will be looking for it. The directory where the application binary resides is one of those places but not the only one.


-why to build Qt in debug mode?
So that you can peek inside internal Qt library calls.


-mingw's gdb isn't enough to debug Qt applications since we're using Qt's sources ?
Yes, it is. But it won't tell you much without debugging symbols. Such an experienced C++ programmer as yourself should know that ;)


-what about .pri and .prf ? should i modify one ?
What for?


-why debugger under Qt creator works(just for an application without macro Q_OBJECT) even if Qt isn't buit in debug mode ?
See the answer above.

oswalidos
11th March 2009, 21:48
No, you can place the library in any place the dynamic linker will be looking for it. The directory where the application binary resides is one of those places but not the only one.


but if i move dll to other directory,i can't run executable ,error :exited with code -1073741819 .

anyway,my problem is how to buid any application with no error ,the code of real_time_plot must work with no error !

so could you tell me if there is a problem with my .pro ?
i found here :


If you are working with a DLL on Windows you also have to add:

DEFINES += QWT_DLL

The Qwt tarball also includes a qwt.prf file. When you have adjusted and installed it, it does the configurations lines above for you and you can simply write:

CONFIG += qwt


i can't do like he said , i can't got what he mean :
-if you're working with dll
- qwt tarball
-qwt.prf

thanks for your help

wysota
11th March 2009, 22:23
but if i move dll to other directory,i can't run executable ,error :exited with code -1073741819 .
The application probably picks up another version of the library that resides somewhere in your system.


anyway,my problem is how to buid any application with no error ,the code of real_time_plot must work with no error !
Your application builds without error. It just doesn't run. That's two different things.


so could you tell me if there is a problem with my .pro ?
No, your pro is fine.


i can't do like he said , i can't got what he mean :
-if you're working with dll
- qwt tarball
-qwt.prf
What do you mean you can't do it?

oswalidos
11th March 2009, 22:47
i installed Qt 4.4 and 4.5 and qwt 5.1.1 and 5.3 and 5.2 and visual studio 2008 and 2 or 3 mingw ,so my environnement can get confused ? :confused:


What do you mean you can't do it?

i don't have :
DEFINES += QWT_DLL
CONFIG += qwt
in my pro ,i can't do that cuz i don't understand why should i do that , in addition i tried but it makes other problems

thanks again

wysota
11th March 2009, 23:20
i don't have :
DEFINES += QWT_DLL
CONFIG += qwt
in my pro ,i can't do that cuz i don't understand why should i do that , in addition i tried but it makes other problems

If the guy tells you to do it, then do it. If you have problems, it means you have to solve them. Those statements initialize the use of Qwt in your application.

I suggest you uninstall everything and start from scratch slowly, without shooting blind. Install one development environment and one Qt version. Then install one version of Qwt (follow the install guide that comes with Qwt), add what's needed to your project file and then start developing software based on Qwt.

oswalidos
11th March 2009, 23:37
ok ,i'll restart everything ,by the way the guy didn't tell me,i found it somewhere
thanks for your help :)

oswalidos
12th March 2009, 22:46
hi again ,
i restart everything and my news :
-able to debug my application with visual c++ debugger (given with Qt creator)
-i downlaod mingw while i'm installing Qt 4.5 .
-is it normal to don't use the mingw debugger ? (anyway it works)
-i still have to copy qwtd5.dll to debug folder of my application ,otherwise with debugging i got a runtime error ! (can you help me for that ?)
-i can back now to my problem : displaying point by point a curve .

now the code i posted works with no error but the curve don't appear point by point ,first time no curve ,after some seconds i have to refresh the window to see the curve .

i think if Qt run only one thread(i can see that in debugger) for my application i can't get what want ,i may should create a thread for the methode which call timer ,to get two parellel threads ,one to show the window and second takes care of the timer and giving data .

am i right?

thanks for your help :)

wysota
13th March 2009, 00:05
No, you are wrong. See the attachment.

About the DLL - place it in your Windows\System32 folder or along other Qt DLL files.

oswalidos
13th March 2009, 15:37
it was a nice conversation :D
coping my dll under system32 solve the problem.
about code i have just to put replot(); in the right places and it works :



void Plot::onTimeout(){ //each timeout data will
currentPointPosition++; // be added to the curve
if(currentPointPosition>1000) currentPointPosition = 1;
curve->setData(x, y, currentPointPosition);
replot();
}

void Plot::pointByPoint(){ //calling this method provoque painting curve "slowly"
for(int i=0;i<1000;i++){
timer->start(10);
}
}

//in constructor
connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
// add curves
curve = new QwtPlotCurve("Vitesse");
curve->setPen(QPen(Qt::green));
curve->attach(this);
currentPointPosition=1;
curve->setData(x, y, currentPointPosition);
replot();


think you so much for your help :)
how to mark this thread as solved ?