Results 1 to 9 of 9

Thread: x-bottom scale div linked to pixels even if resizing

  1. #1
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default x-bottom scale div linked to pixels even if resizing

    Hello,

    I tried to make a fixed bottom axis (1 unit = 1 pixel), when resizing doesn't change scale but add/remove some units.

    QwtPlot* m_pPlot;
    QVector<QPointF> points; (sample)
    QRectF m_BaseRec; (representing the actual unzoomed canvas rect)
    QTimer timer; (simulate continuous data reception)
    Qt Code:
    1. void Widget::resizeEvent(QResizeEvent *e) {
    2. if (m_pPlot->isVisible()) {
    3. QSize oldSize(e->oldSize());
    4. QSize size(e->size());
    5.  
    6. if (points.size() >= m_BaseRec.width() && size.width() < oldSize.width()) {
    7. points.remove(0, oldSize.width() - size.width());
    8. m_BaseRec.moveRight(m_BaseRec.right()-m_pPlot->canvas()->width()+m_BaseRec.width());
    9. }
    10.  
    11. m_BaseRec.setWidth(m_pPlot->canvas()->width());
    12. m_BaseRec.setHeight(m_pPlot->axisScaleDiv(QwtPlot::yLeft)->range());
    13. }
    14.  
    15. if (timer.isActive()) {
    16. m_pPlot->setAxisScale(QwtPlot::xBottom, m_BaseRec.left(), m_BaseRec.right(), stepSize);
    17. }
    18.  
    19. QWidget::resizeEvent(e);
    20. }
    To copy to clipboard, switch view to plain text mode 

    But for this easy graphical purpose, it "flashes" a lot, always reploting. Is there a better way to do this ?
    - reduce width push the last right point to stay against the right edge - the first and non-visible points are removed from the "points" vector
    - increase width add empty space right to the last point

  2. #2
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    Help please ! There is several classes to manage axis scales and it's hard to understand specific "curve" vocabulary for me so i think i could miss something.

  3. #3
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,312
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    Check QwtPlotRescaler and the navigation example.

    Uwe

  4. #4
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    One of the examples that I didn't study because I didn't understand (that it was about rescaling). Seems perfect, thx

  5. #5
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    Ok so, my code is cleaner using the right class. But it "flashes" again and I know why. I set the step size with setAxisScale at each new value, but when i call replot(), it auto-adjust the step size, then I set it again with the next value, then replot(), etc. Is there a way to fix this ?

    This is my code, from a simple graphical QWidget project (with ui) if you want to test the behavior.

    Widget.ui
    Qt Code:
    1. <ui version="4.0">
    2. <class>Widget</class>
    3. <widget class="QWidget" name="Widget">
    4. <property name="geometry">
    5. <rect>
    6. <x>0</x>
    7. <y>0</y>
    8. <width>706</width>
    9. <height>366</height>
    10. </rect>
    11. </property>
    12. <property name="windowTitle">
    13. <string>Widget</string>
    14. </property>
    15. <layout class="QHBoxLayout" name="horizontalLayout">
    16. <item>
    17. <layout class="QVBoxLayout" name="verticalLayout">
    18. <property name="spacing">
    19. <number>0</number>
    20. </property>
    21. <item>
    22. <widget class="QPushButton" name="reset">
    23. <property name="text">
    24. <string>Stop</string>
    25. </property>
    26. </widget>
    27. </item>
    28. </layout>
    29. </item>
    30. </layout>
    31. </widget>
    32. <layoutdefault spacing="6" margin="11"/>
    33. <resources/>
    34. <connections/>
    35. </ui>
    To copy to clipboard, switch view to plain text mode 

    Widget.h
    Qt Code:
    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3.  
    4. #include <QWidget>
    5. #include <QTimer>
    6.  
    7. namespace Ui {
    8. class Widget;
    9. }
    10.  
    11. class QSizeGrip;
    12. class QwtPlot;
    13. class PlotZoomer;
    14. class QwtPlotRescaler;
    15.  
    16. class Widget : public QWidget
    17. {
    18. Q_OBJECT
    19.  
    20. public:
    21. explicit Widget(QWidget *parent = 0);
    22. ~Widget();
    23.  
    24. private:
    25. Ui::Widget *ui;
    26.  
    27. QVector<QPointF> points;
    28. qreal curX;
    29. QTimer timer;
    30.  
    31. QSizeGrip* m_pSizeGrip;
    32. QwtPlot* m_pPlot;
    33. QwtPlotCurve* m_pCurve;
    34. QwtPlotGrid* m_pGrid;
    35. int stepSize;
    36. PlotZoomer* m_pZoomer;
    37. QwtPlotMagnifier* m_pMagnifier;
    38. QwtPlotPanner* m_pPanner;
    39. QwtPlotRescaler* m_pRescaler;
    40.  
    41. void resizeEvent(QResizeEvent *e);
    42.  
    43. private slots:
    44. void newValue();
    45. void playPause();
    46. };
    47.  
    48. #endif // WIDGET_H
    To copy to clipboard, switch view to plain text mode 

    Widget.cpp
    Qt Code:
    1. #include "Widget.h"
    2. #include "ui_Widget.h"
    3.  
    4. #include <QTime>
    5. #include <QSizeGrip>
    6. #include <QResizeEvent>
    7. #include <qmath.h>
    8.  
    9. #include <qwt_plot.h>
    10. #include <qwt_plot_grid.h>
    11. #include <qwt_plot_curve.h>
    12. #include <qwt_plot_canvas.h>
    13. #include <qwt_plot_layout.h>
    14. #include <qwt_plot_zoomer.h>
    15. #include <qwt_plot_panner.h>
    16. #include <qwt_plot_magnifier.h>
    17. #include <qwt_plot_rescaler.h>
    18. #include <qwt_scale_draw.h>
    19.  
    20. class PlotZoomer : public QwtPlotZoomer
    21. {
    22. public:
    23. explicit PlotZoomer(QwtPlotCanvas *canvas);
    24.  
    25. void setZoomBase( const QRectF &base );
    26. };
    27.  
    28. PlotZoomer::PlotZoomer(QwtPlotCanvas *canvas) :
    29. QwtPlotZoomer(canvas)
    30. {
    31. }
    32.  
    33. void PlotZoomer::setZoomBase(const QRectF &base)
    34. {
    35. if ( !plot() )
    36. return;
    37.  
    38. int currentIndex = zoomRectIndex();
    39. QStack<QRectF> stack = zoomStack();
    40. stack.replace(0, base);
    41. setZoomStack(stack, 0);
    42. zoom(currentIndex);
    43. }
    44.  
    45. Widget::Widget(QWidget *parent) :
    46. QWidget(parent),
    47. ui(new Ui::Widget),
    48. m_pSizeGrip(new QSizeGrip(this)),
    49. curX( 0 ),
    50. stepSize( 50 ),
    51. m_pPlot( new QwtPlot( this ) ),
    52. m_pCurve( new QwtPlotCurve ),
    53. m_pGrid( new QwtPlotGrid )
    54. {
    55. ui->setupUi(this);
    56.  
    57. m_pPlot->canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false);
    58. m_pPlot->setCanvasBackground(Qt::black);
    59. m_pPlot->setWindowFlags( m_pPlot->windowFlags() | Qt::SubWindow );
    60. m_pPlot->plotLayout()->setAlignCanvasToScales(true);
    61.  
    62. m_pRescaler = new QwtPlotRescaler(m_pPlot->canvas());
    63. m_pRescaler->setAspectRatio(QwtPlot::yLeft, 0.0);
    64.  
    65. m_pSizeGrip->resize(12,12);
    66. m_pSizeGrip->move(width()-12,height()-12);
    67.  
    68. m_pCurve->setPen(QColor(Qt::green));
    69. m_pCurve->setRenderHint(QwtPlotItem::RenderAntialiased);
    70. m_pCurve->attach(m_pPlot);
    71.  
    72. m_pGrid->setPen(QColor(Qt::white));
    73. m_pGrid->attach(m_pPlot);
    74.  
    75. m_pZoomer = new PlotZoomer( m_pPlot->canvas() );
    76. m_pZoomer->setRubberBandPen(QColor(Qt::red));
    77. m_pZoomer->setTrackerPen( QColor( Qt::red ) );
    78. m_pZoomer->setTrackerFont( QFont( "Helvetica [Cronyx]", 12, QFont::Bold ) );
    79. m_pZoomer->setTrackerMode( PlotZoomer::AlwaysOn );
    80. m_pZoomer->setMousePattern( QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier );
    81. m_pZoomer->setMousePattern( QwtEventPattern::MouseSelect3, Qt::RightButton );
    82.  
    83. m_pMagnifier = new QwtPlotMagnifier( m_pPlot->canvas() );
    84. m_pMagnifier->setMouseButton( Qt::MidButton );
    85.  
    86. m_pPanner = new QwtPlotPanner( m_pPlot->canvas() );
    87. m_pPanner->setMouseButton( Qt::LeftButton, Qt::ControlModifier );
    88.  
    89. ui->verticalLayout->addWidget( m_pPlot );
    90.  
    91. connect( &timer, SIGNAL( timeout() ), SLOT( newValue() ) );
    92. connect( ui->reset, SIGNAL( clicked() ), SLOT( playPause() ) );
    93.  
    94. qsrand( QTime::currentTime().msec() );
    95. playPause();
    96. }
    97.  
    98. Widget::~Widget()
    99. {
    100. delete ui;
    101. }
    102.  
    103. void Widget::newValue()
    104. {
    105. points << QPointF(curX++, qSin(curX/30)*100);//qrand()%201 - 100);
    106.  
    107. if (points.size() > m_pPlot->canvas()->width()) {
    108. m_pRescaler->setExpandingDirection(QwtPlotRescaler::ExpandDown);
    109. points.remove(0);
    110. }
    111.  
    112. int left (curX > points.size() ? curX - points.size() : 0);
    113. m_pPlot->setAxisScale(QwtPlot::xBottom, left, left + m_pPlot->canvas()->width(), stepSize);
    114.  
    115. m_pCurve->setSamples(points);
    116. m_pPlot->replot();
    117. }
    118.  
    119. void Widget::playPause() {
    120. bool wasActive(timer.isActive());
    121.  
    122. m_pZoomer->setEnabled(wasActive);
    123. m_pMagnifier->setEnabled(wasActive);
    124. m_pPanner->setEnabled(wasActive);
    125. m_pPlot->axisScaleDraw(QwtPlot::xBottom)->enableComponent(QwtAbstractScaleDraw::Labels, wasActive);
    126.  
    127. if (!wasActive) {
    128. m_pZoomer->zoom(0);
    129. ui->reset->setText("Stop");
    130. points.clear();
    131. curX = 0;
    132. m_pPlot->setAxisScale(QwtPlot::xBottom, 0, m_pPlot->canvas()->width(), stepSize);
    133. m_pPlot->setAxisScale(QwtPlot::yLeft, 0, 0, 0);
    134. m_pPlot->setAxisAutoScale(QwtPlot::yLeft);
    135. m_pPlot->setContentsMargins(0,0,0,15);
    136. timer.start(20);
    137. } else {
    138. timer.stop();
    139. ui->reset->setText("Start");
    140. m_pZoomer->setZoomBase(QRectF(m_pPlot->axisScaleDiv(QwtPlot::xBottom)->lowerBound(), m_pPlot->axisScaleDiv(QwtPlot::yLeft)->lowerBound(), m_pPlot->axisScaleDiv(QwtPlot::xBottom)->range(), m_pPlot->axisScaleDiv(QwtPlot::yLeft)->range()));
    141. m_pPlot->setContentsMargins(0,0,0,0);
    142. m_pPlot->replot();
    143. }
    144. }
    145.  
    146. void Widget::resizeEvent(QResizeEvent *e) {
    147. QWidget::resizeEvent(e);
    148. if (m_pPlot->isVisible()) {
    149. QSize oldSize(e->oldSize());
    150. QSize size(e->size());
    151.  
    152. if (points.size() >= m_pPlot->canvas()->width() && size.width() < oldSize.width()) {
    153. m_pRescaler->setExpandingDirection(QwtPlotRescaler::ExpandDown);
    154. points.remove(0, oldSize.width() - size.width());
    155. } else {
    156. m_pRescaler->setExpandingDirection(QwtPlotRescaler::ExpandUp);
    157. }
    158. }
    159.  
    160. m_pSizeGrip->move(width()-12, height()-12);
    161. }
    To copy to clipboard, switch view to plain text mode 

    Another strange behavior: after zooming with a box (when it is paused), unzooming with right click one more time than the 0 level do a one-pixel horizontal shift... A way to avoid this ?

    Edit: And I can't reduce the vertical size as much as I want...
    Last edited by Troudhyl; 26th May 2011 at 15:39. Reason: nicer code

  6. #6
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    I think I should increase the max number of steps and only it, I don't know how. I tried
    Qt Code:
    1. double x1(0.0), x2(0.0), step(stepSize); // I don't care about these parameters...
    2. m_pPlot->axisScaleEngine(QwtPlot::xBottom)->autoScale(1000, x1, x2, step);
    To copy to clipboard, switch view to plain text mode 
    => no change.

    Edit : it is something like setAxisMaxMajor (because it's good when the width is smaller than 8 steps), but setting it is like setting a low limit to rescaling :/
    Last edited by Troudhyl; 27th May 2011 at 09:25.

  7. #7
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,312
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    I didn't get what your request is about in detail and posting even more code won't make things clearer.

    Better build a small (!) demo application I can compile and run on my system.

    Uwe

  8. #8
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    It really is a small demo (it only build a curve with data simulation and start/stop button), as I said if you create a graphical QWidget default project in Qt Creator (with main.cpp, Widget.h, Widget.cpp and Widget.ui) and copy-paste this code, you should run my work and see what I mean. I attach the project (.zip).

    Then just rescale and you will see the fight between my setAxisScale(...,stepSize) and the axisMaxMajor at each replot().

    Qt Code:
    1. void Widget::newValue()
    2. {
    3. points << QPointF(curX++, qSin(curX/30)*100);
    4.  
    5. if (points.size() > m_pPlot->canvas()->width()) {
    6. m_pRescaler->setExpandingDirection(QwtPlotRescaler::ExpandDown);
    7. points.remove(0);
    8. }
    9.  
    10. int left (curX > points.size() ? curX - points.size() : 0);
    11. m_pPlot->setAxisScale(QwtPlot::xBottom, left, left + m_pPlot->canvas()->width(), stepSize);
    12.  
    13. m_pCurve->setSamples(points);
    14. m_pPlot->replot();
    15. }
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files
    Last edited by Troudhyl; 27th May 2011 at 09:49.

  9. #9
    Join Date
    May 2011
    Posts
    21
    Thanks
    1
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: x-bottom scale div linked to pixels even if resizing

    I fixed it by adding this code in resizeEvent:

    Qt Code:
    1. if (timer.isActive()) {
    2. m_pPlot->setAxisMaxMajor( QwtPlot::xBottom, m_pPlot->canvas()->width() / stepSize + 1 );
    3. }
    To copy to clipboard, switch view to plain text mode 

    I fix the resizing comportment when paused too. See new attachment. The comportment is good, but maybe not optimized using the good tools... There are some one-pixel shifts again, not with unzooming (fixed too but I don't know why), but with resizing again.

    The last, big, problem is the "pause" mode.
    Qt Code:
    1. timer.stop();
    2. ui->reset->setText("Start");
    3. m_pZoomer->setZoomBase(QRectF(m_pPlot->axisScaleDiv(QwtPlot::xBottom)->lowerBound(), m_pPlot->axisScaleDiv(QwtPlot::yLeft)->lowerBound(), m_pPlot->axisScaleDiv(QwtPlot::xBottom)->range(), m_pPlot->axisScaleDiv(QwtPlot::yLeft)->range()));
    4. m_pRescaler->setRescalePolicy(QwtPlotRescaler::Fixed);
    5. m_pPlot->setContentsMargins(0,0,0,0);
    6. m_pPlot->replot();
    To copy to clipboard, switch view to plain text mode 
    It forces a low limit to resize, and often increase the size of the curve when pausing, if it is too small.

    Sorry again for my bad english (rescale != resize ?), I hope you understand the main points...

    Edit: It is because of m_pPlot->setContentsMargins(0,0,0,0); . But I chose to not display bottom tick labels when playing because numbers are not clipped and make the plot trembling. And to just hide/show, a margin is necessary when hidden, otherwise it resizes the canvas. So I know the cause but not the solution, you can help me Then you can add it to Qwt examples
    Attached Files Attached Files
    Last edited by Troudhyl; 27th May 2011 at 12:46.

Similar Threads

  1. Replies: 3
    Last Post: 2nd March 2010, 20:58
  2. Why must I pad boundingRect() by 7 pixels
    By xenome in forum Qt Programming
    Replies: 3
    Last Post: 10th September 2009, 14:07
  3. Pixels
    By Dante in forum Qt Programming
    Replies: 1
    Last Post: 21st April 2009, 20:50
  4. Replies: 13
    Last Post: 12th June 2008, 13:23
  5. Replies: 7
    Last Post: 15th November 2007, 17:19

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.