Problems with replot() and dynamical plotting
Hi there,
I have a problem with dynamically updating a QwtPlot. I based my code on the example "data_plot" but instead of having a timer inside of my data_plot-object I created a slot which gives me new values to add. Here is the code:
Code:
#ifndef _DATA_PLOT_H
#define _DATA_PLOT_H 1
#include <qwt_plot.h>
const int PLOT_SIZE = 201; // 0 to 200
{
Q_OBJECT
public:
public slots:
void refreshP(double val);
private:
double d_x[PLOT_SIZE];
double d_y[PLOT_SIZE];
double d_z[PLOT_SIZE];
};
#endif
Code:
#include <stdlib.h>
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_widget.h>
#include <qwt_legend.h>
#include <qwt_scale_draw.h>
#include <qwt_math.h>
#include "data_plot.h"
#include <iostream>
{
// Disable polygon clipping
// We don't need the cache here
// Initialize data
for (int i = 0; i< PLOT_SIZE; i++)
{
d_x[i] = 0.5 * i; // time axis
d_y[i] = 0;
}
// Insert new curves
cRight->attach(this);
// Set curve styles
cRight
->setPen
(QPen(Qt
::red));
// Attach (don't copy) data. Both curves use the same x array.
cRight->setRawData(d_x, d_y, PLOT_SIZE);
}
// Generate new values
void DataPlot::refreshP(double val)
{
for ( int j = 0; j < PLOT_SIZE - 1; j++ )
d_y[j] = d_y[j+1];
d_y[PLOT_SIZE - 1] = val;
// update the display
replot();
}
Then here is how it is used:
Code:
#include "window.h"
{
.
.
.
Widget2D *evolving_obj = new Widget2D;
DataPlot *dynamics = new DataPlot(this);
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot())); // this does not work
connect(someButton , SIGNAL(clicked()), dynamics, SLOT(replot())); //this works!
.
.
.
}
Widget2D has a timer and produces data and of course Widget2D has a signal "void newSignal(double nS);" with the corresponding body. The new data is correctly stores in the array d_Y but the plot is not updated.
If I however click on the someButton, the plot is updated.
I have no clue how to solve this problem. Thanks for your help.
Re: Problems with replot() and dynamical plotting
Hi gi0rgi0ne,
Your slot is wrong in the connection:
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
use this:
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
Hüseyin
Re: Problems with replot() and dynamical plotting
Thanks for your help Hüseyin,
unfortunaltely this does not help. I mixed up some code while posting, sorry.
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
is the way I implemented it, and it did not work.
My alternative was to overwrite replot()
Code:
void DataPlot::replot()
{
refreshP(1.0); //this just to give it some value
}
then I commented the "replot()" statement out of refreshP() and use the following connect:
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
This did not help either.
Any idea?
Re: Problems with replot() and dynamical plotting
Hmm, it seems you override the original replot.
Maybe closing the auto replot works:
Code:
{
setAutoReplot(false);
or try to not override replot.
Hüseyin
Re: Problems with replot() and dynamical plotting
That did not help either.
What is funny is that
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
does not work.
Code:
connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
does not have any effect, HOWEVER
Code:
connect(someButton, SIGNAL(clicked()), dynamics, SLOT(replot()));
works!! I do not understand that.
Why does one SIGNAL work and the other one does not??
Re: Problems with replot() and dynamical plotting
Can you give the "Window.h". I want to see that your signal definition in the header. And also want to see the timer configuration (timer->start(), connect(timer,...) ...etc.) if it is possible.
Sometimes different function names doesn't give any error but it also doesn't work.
Hüseyin
Re: Problems with replot() and dynamical plotting
my window.h
Code:
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
#include <QLabel>
#include <QApplication>
#include <QFont>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
#include <QtGui>
#include <iostream>
#include "widget2d.h"
#include "lcdrange.h"
#include <qapplication.h>
#include <qmainwindow.h>
#include <qwt_counter.h>
#include <qtoolbar.h>
#include <qlabel.h>
#include <qlayout.h>
#include "data_plot.h"
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
{
public:
};
#endif
and here the code of the widget2d.h, where the signals and the timer are:
Code:
#ifndef WIDGET2D_H
#define WIDGET2D_H
#include <QWidget>
#include <QImage>
#include <QRgb>
#include <iostream>
//#include <cstdlib>
#include <QtGui>
//#include <dranxor.h>
#include "ExVolWid.h"
{
Q_OBJECT
public:
QSize minimumSizeHint
() const;
public slots:
void nextAnimationFrame();
void setGridScale(int value);
void ScaleGrid();
void changeStatus(bool s);
void changeRes(int value);
signals:
void scaleChanged(int newValue);
void newSignal(double nS);
protected:
private:
int ll;
bool isStarted;
bool isPaused;
bool changed;
int gridScale;
ExVolWid* my_system;
};
#endif
and widget2d.cpp code :
Code:
#include "widget2d.h"
#define min(a, b) a < b ? a : b
{
ll = 50;
gridScale = 400;
changed = true;
my_system = new ExVolWid(ll,1.0);
}
////////////
QSize Widget2D
::minimumSizeHint() const {
}
////////////
void Widget2D::setGridScale(int value)
{
gridScale = value;
emit scaleChanged(gridScale);
}
////////////
void Widget2D::ScaleGrid()
{
gridScale = min(size().height(),size().width());
update();
emit scaleChanged(gridScale);
}
//////////////
void Widget2D::changeStatus(bool s)
{
if (s){
if (changed){
delete my_system;
my_system = new ExVolWid(ll,1.0);
changed = false;
}
timer.start(50,this);
}
else {
if (timer.isActive())
timer.stop();
}
}
//////////////////
update();
}
//////////////////
{
painter.drawImage(0,0,my_system->get_pic().scaled(gridScale,gridScale));
emit newSignal(my_system->getSignal());
my_system->evolve();
}
///////////////////
void Widget2D::changeRes(int value)
{
ll = value;
changed = true;
}
///////////////////
thanks for your help.
Re: Problems with replot() and dynamical plotting
Sorry, I am not good at paintEvent related subjects. But it seems the problem is your style when using the timer event.
Try to get data in timer event, and replot it in the timer.
Maybe calling the replot in the paintEvent is confusing.
Hüseyin
Re: Problems with replot() and dynamical plotting
I do not use paintEvent with the data_plot class. I just use it to let my Widget2d evolve, this is unrelated to the data_plot. My Widget2d-object (evolving_obj) then sends a new value via newSignal(double nS) to the data_plot object.
So data_plot does not need a timer, it should update when ever it gets a new value.
Quote:
Maybe calling the replot in the paintEvent is confusing.
The methods "void Widget2D::timerEvent(QTimerEvent *)" and "void Widget2D::paintEvent(QPaintEvent *)" are only talking to the Widget2D object and should be (at least I hope, tell me if I am wrong) completely unrelated to the data_plot-object.