Results 1 to 9 of 9

Thread: Problems with replot() and dynamical plotting

  1. #1
    Join Date
    Apr 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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:

    Qt Code:
    1. #ifndef _DATA_PLOT_H
    2. #define _DATA_PLOT_H 1
    3.  
    4. #include <qwt_plot.h>
    5.  
    6. const int PLOT_SIZE = 201; // 0 to 200
    7.  
    8. class DataPlot : public QwtPlot
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. DataPlot(QWidget* = NULL);
    14.  
    15. public slots:
    16. void refreshP(double val);
    17.  
    18. private:
    19.  
    20. double d_x[PLOT_SIZE];
    21. double d_y[PLOT_SIZE];
    22. double d_z[PLOT_SIZE];
    23. };
    24.  
    25. #endif
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <stdlib.h>
    2. #include <qwt_painter.h>
    3. #include <qwt_plot_canvas.h>
    4. #include <qwt_plot_marker.h>
    5. #include <qwt_plot_curve.h>
    6. #include <qwt_scale_widget.h>
    7. #include <qwt_legend.h>
    8. #include <qwt_scale_draw.h>
    9. #include <qwt_math.h>
    10. #include "data_plot.h"
    11. #include <iostream>
    12.  
    13. DataPlot::DataPlot(QWidget *parent): QwtPlot(parent)
    14. {
    15.  
    16. // Disable polygon clipping
    17. QwtPainter::setDeviceClipping(false);
    18.  
    19. // We don't need the cache here
    20. canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
    21. canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
    22.  
    23.  
    24. // Initialize data
    25. for (int i = 0; i< PLOT_SIZE; i++)
    26. {
    27. d_x[i] = 0.5 * i; // time axis
    28. d_y[i] = 0;
    29. }
    30.  
    31. // Insert new curves
    32. QwtPlotCurve *cRight = new QwtPlotCurve("Data Moving Right");
    33. cRight->attach(this);
    34.  
    35. // Set curve styles
    36. cRight->setPen(QPen(Qt::red));
    37.  
    38. // Attach (don't copy) data. Both curves use the same x array.
    39. cRight->setRawData(d_x, d_y, PLOT_SIZE);
    40.  
    41. }
    42.  
    43. // Generate new values
    44. void DataPlot::refreshP(double val)
    45. {
    46. for ( int j = 0; j < PLOT_SIZE - 1; j++ )
    47. d_y[j] = d_y[j+1];
    48.  
    49. d_y[PLOT_SIZE - 1] = val;
    50. // update the display
    51. replot();
    52.  
    53. }
    To copy to clipboard, switch view to plain text mode 

    Then here is how it is used:

    Qt Code:
    1. #include "window.h"
    2.  
    3. Window::Window(QWidget *parent) : QWidget(parent)
    4. {
    5. .
    6. .
    7. .
    8. Widget2D *evolving_obj = new Widget2D;
    9. DataPlot *dynamics = new DataPlot(this);
    10. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot())); // this does not work
    11. connect(someButton , SIGNAL(clicked()), dynamics, SLOT(replot())); //this works!
    12.  
    13. .
    14. .
    15. .
    16. }
    To copy to clipboard, switch view to plain text mode 

    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.

  2. #2
    Join Date
    Mar 2009
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problems with replot() and dynamical plotting

    Hi gi0rgi0ne,
    Your slot is wrong in the connection:
    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
    To copy to clipboard, switch view to plain text mode 
    use this:
    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
    To copy to clipboard, switch view to plain text mode 


    Hüseyin
    Last edited by huseyinkozan; 8th April 2009 at 11:44.

  3. #3
    Join Date
    Apr 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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.

    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
    To copy to clipboard, switch view to plain text mode 
    is the way I implemented it, and it did not work.

    My alternative was to overwrite replot()
    Qt Code:
    1. void DataPlot::replot()
    2. {
    3. refreshP(1.0); //this just to give it some value
    4. QwtPlot::replot();
    5. }
    To copy to clipboard, switch view to plain text mode 

    then I commented the "replot()" statement out of refreshP() and use the following connect:
    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
    To copy to clipboard, switch view to plain text mode 

    This did not help either.
    Any idea?

  4. #4
    Join Date
    Mar 2009
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problems with replot() and dynamical plotting

    Hmm, it seems you override the original replot.
    Maybe closing the auto replot works:
    Qt Code:
    1. DataPlot::DataPlot(QWidget *parent): QwtPlot(parent)
    2. {
    3. setAutoReplot(false);
    To copy to clipboard, switch view to plain text mode 
    or try to not override replot.


    Hüseyin

  5. #5
    Join Date
    Apr 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems with replot() and dynamical plotting

    That did not help either.

    What is funny is that
    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(refreshP(double)));
    To copy to clipboard, switch view to plain text mode 
    does not work.
    Qt Code:
    1. connect(evolving_obj, SIGNAL(newSignal(double)), dynamics, SLOT(replot()));
    To copy to clipboard, switch view to plain text mode 
    does not have any effect, HOWEVER
    Qt Code:
    1. connect(someButton, SIGNAL(clicked()), dynamics, SLOT(replot()));
    To copy to clipboard, switch view to plain text mode 
    works!! I do not understand that.

    Why does one SIGNAL work and the other one does not??

  6. #6
    Join Date
    Mar 2009
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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

  7. #7
    Join Date
    Apr 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Problems with replot() and dynamical plotting

    my window.h

    Qt Code:
    1. #ifndef WINDOW_H
    2. #define WINDOW_H
    3.  
    4. #include <QWidget>
    5. #include <QLabel>
    6. #include <QApplication>
    7. #include <QFont>
    8. #include <QGridLayout>
    9. #include <QHBoxLayout>
    10. #include <QPushButton>
    11. #include <QVBoxLayout>
    12. #include <QtGui>
    13.  
    14. #include <iostream>
    15.  
    16. #include "widget2d.h"
    17. #include "lcdrange.h"
    18.  
    19.  
    20. #include <qapplication.h>
    21. #include <qmainwindow.h>
    22. #include <qwt_counter.h>
    23. #include <qtoolbar.h>
    24. #include <qlabel.h>
    25. #include <qlayout.h>
    26. #include "data_plot.h"
    27.  
    28.  
    29.  
    30. QT_BEGIN_NAMESPACE
    31. class QLabel;
    32. QT_END_NAMESPACE
    33.  
    34. class Window : public QWidget
    35. {
    36.  
    37. public:
    38. Window(QWidget *parent = 0);
    39.  
    40.  
    41.  
    42. };
    43.  
    44. #endif
    To copy to clipboard, switch view to plain text mode 

    and here the code of the widget2d.h, where the signals and the timer are:

    Qt Code:
    1. #ifndef WIDGET2D_H
    2. #define WIDGET2D_H
    3.  
    4. #include <QWidget>
    5. #include <QImage>
    6. #include <QRgb>
    7. #include <iostream>
    8. //#include <cstdlib>
    9. #include <QtGui>
    10. //#include <dranxor.h>
    11. #include "ExVolWid.h"
    12.  
    13. class Widget2D : public QWidget
    14. {
    15. Q_OBJECT
    16.  
    17. public:
    18. Widget2D(QWidget *parent = 0);
    19.  
    20. QSize minimumSizeHint() const;
    21.  
    22. public slots:
    23. void nextAnimationFrame();
    24. void setGridScale(int value);
    25. void ScaleGrid();
    26. void changeStatus(bool s);
    27. void changeRes(int value);
    28.  
    29. signals:
    30. void scaleChanged(int newValue);
    31. void newSignal(double nS);
    32.  
    33. protected:
    34. void paintEvent(QPaintEvent *event);
    35. void timerEvent(QTimerEvent *event);
    36.  
    37. private:
    38. int ll;
    39. bool isStarted;
    40. bool isPaused;
    41. bool changed;
    42. int gridScale;
    43. ExVolWid* my_system;
    44. QBasicTimer timer;
    45. };
    46.  
    47. #endif
    To copy to clipboard, switch view to plain text mode 

    and widget2d.cpp code :

    Qt Code:
    1. #include "widget2d.h"
    2. #define min(a, b) a < b ? a : b
    3.  
    4. Widget2D::Widget2D(QWidget *parent) : QWidget(parent)
    5. {
    6.  
    7. ll = 50;
    8. gridScale = 400;
    9. setBackgroundRole(QPalette::Base);
    10. setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    11. changed = true;
    12. my_system = new ExVolWid(ll,1.0);
    13.  
    14. }
    15. ////////////
    16. QSize Widget2D::minimumSizeHint() const
    17. {
    18. return QSize(400, 400);
    19. }
    20. ////////////
    21. void Widget2D::setGridScale(int value)
    22. {
    23. gridScale = value;
    24. emit scaleChanged(gridScale);
    25. }
    26. ////////////
    27. void Widget2D::ScaleGrid()
    28. {
    29. gridScale = min(size().height(),size().width());
    30. update();
    31. emit scaleChanged(gridScale);
    32. }
    33. //////////////
    34. void Widget2D::changeStatus(bool s)
    35. {
    36. if (s){
    37. if (changed){
    38. delete my_system;
    39. my_system = new ExVolWid(ll,1.0);
    40. changed = false;
    41. }
    42. timer.start(50,this);
    43. }
    44. else {
    45. if (timer.isActive())
    46. timer.stop();
    47. }
    48. }
    49. //////////////////
    50. void Widget2D::timerEvent(QTimerEvent *){
    51. update();
    52. }
    53. //////////////////
    54. void Widget2D::paintEvent(QPaintEvent *)
    55. {
    56. QPainter painter(this);
    57. painter.drawImage(0,0,my_system->get_pic().scaled(gridScale,gridScale));
    58. emit newSignal(my_system->getSignal());
    59. my_system->evolve();
    60. }
    61. ///////////////////
    62. void Widget2D::changeRes(int value)
    63. {
    64. ll = value;
    65. changed = true;
    66. }
    67. ///////////////////
    To copy to clipboard, switch view to plain text mode 

    thanks for your help.

  8. #8
    Join Date
    Mar 2009
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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

  9. #9
    Join Date
    Apr 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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.

    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.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.