Since the QwtPlotZoomer can not handle multiple y-Axis I have tried to implement a single Zoomer class handling both axis and thus two zoomer instances at once (I extended the class from one zoomer to a second).

However what happens is that the zoomed region is wrong. I susspect that the left zoomer is called first, and then the right zoomer on an already zoomed region (because I sometimes see a second rectangle and then a second zoom).

Here is a debug output:
--- Zoom Stack -----------------
0 *, QRectF(-10,3.72008e-44 19.98x1) , Y2: QRectF(-10,-0.172354 19.98x3.67272)

--- Zoom Stack -----------------
0 , QRectF(-10,3.72008e-44 19.98x1) , Y2: QRectF(-10,-0.172354 19.98x3.67272)

1 *, QRectF(-0.653651,3.72008e-44 1.23913x0.501961) , Y2: QRectF(-2.51714,-0.1
72354 4.97571x1.84356)
The actual zoom region was (X1Y1): (-2.5,0.5) - (2.5,0.0)

The code of the class is the following:
Qt Code:
  1. #include "Zoomer.h"
  2.  
  3. #include <qwt_plot.h>
  4. #include <qwt_plot_panner.h>
  5. #include <qwt_scale_widget.h>
  6. #include <qwt_plot_layout.h>
  7.  
  8. #include <QDebug>
  9.  
  10. // TODO: add documentation
  11.  
  12. class PlotScale{
  13. public:
  14. PlotScale() : enabled(false){}
  15. double min;
  16. double max;
  17. bool enabled;
  18. };
  19.  
  20. class ZoomerPrivate{
  21. public:
  22. ZoomerPrivate(QwtPlot * qwtplot)
  23. : zoomerY2(new QwtPlotZoomer(qwtplot->canvas()))
  24. {
  25. zoomerY2->setAxis(QwtPlot::xBottom, QwtPlot::yRight);
  26. }
  27. PlotScale plotScaleX;
  28. PlotScale plotScaleY;
  29. PlotScale plotScaleX2;
  30. PlotScale plotScaleY2;
  31.  
  32. QScopedPointer<QwtPlotZoomer> zoomerY2;
  33.  
  34. };
  35.  
  36. Zoomer::Zoomer(QwtPlot * qwtplot)
  37. : QwtPlotZoomer(qwtplot->canvas())
  38. , plot(qwtplot)
  39. , d(new ZoomerPrivate(qwtplot))
  40. {
  41. setAxis(QwtPlot::xBottom, QwtPlot::yLeft);
  42. setTrackerMode(QwtPicker::AlwaysOn);
  43. init();
  44. connect(this, SIGNAL(zoomed(const QwtDoubleRect &)), this, SLOT(OnZoomed()));
  45. }
  46.  
  47. Zoomer::~Zoomer()
  48. {
  49.  
  50. }
  51.  
  52. void Zoomer::initScale()
  53. {
  54. d->zoomerY2->setZoomBase(true);
  55. this->setZoomBase(true);
  56. debugZoomerStack();
  57. }
  58.  
  59. /*! \bug{setManualScaleX never used. Manual axis not applied} */
  60. void Zoomer::setScaleX(double min, double max)
  61. {
  62. d->plotScaleX.min = min;
  63. d->plotScaleX.max = max;
  64. d->plotScaleX.enabled = true;
  65. }
  66.  
  67. void Zoomer::setScaleY(double min, double max)
  68. {
  69. d->plotScaleY.min = min;
  70. d->plotScaleY.max = max;
  71. d->plotScaleY.enabled = true;
  72. }
  73.  
  74. void Zoomer::init()
  75. {
  76. // LeftButton for the zooming
  77. // MidButton for the panning
  78. // RightButton: zoom out by 1
  79. // Ctrl+RighButton: zoom out to full size
  80.  
  81. this->setMousePattern(QwtEventPattern::MouseSelect2,
  82. Qt::RightButton, Qt::ControlModifier);
  83. // d->zoomerY2->setMousePattern(QwtEventPattern::MouseSelect2,
  84. // Qt::RightButton, Qt::ControlModifier);
  85. // this->setMousePattern(QwtEventPattern::MouseSelect3,
  86. // Qt::RightButton);
  87.  
  88. // Mid Mouse. Panner moves whole plot area
  89. QwtPlotPanner *panner = new QwtPlotPanner(plot->canvas());
  90. panner->setAxisEnabled(QwtPlot::yRight, plot->axisEnabled(QwtPlot::yRight));
  91. panner->setMouseButton(Qt::MidButton);
  92.  
  93. // Avoid jumping when labels with more/less digits
  94. // appear/disappear when scrolling vertically
  95.  
  96. const QFontMetrics fm(plot->axisWidget(QwtPlot::yLeft)->font());
  97. QwtScaleDraw *sd = plot->axisScaleDraw(QwtPlot::yLeft);
  98. sd->setMinimumExtent( fm.width("100.00") );
  99.  
  100. const QColor c(Qt::darkBlue);
  101. this->setRubberBandPen(c);
  102. this->setTrackerPen(c);
  103.  
  104. // Reinitialized the zoom stack with scaleRect() as base.
  105. // Calls replot before initializing the zoomer with its scales.
  106. initScale();
  107. }
  108.  
  109. /*!
  110.  * modify the visual appearance of tracker text.
  111.  */
  112. QwtText Zoomer::trackerText( const QwtDoublePoint& p ) const
  113. {
  114. QwtText t( QwtPlotPicker::trackerText( p ));
  115.  
  116. QColor c(Qt::white);
  117. c.setAlpha(180);
  118. t.setBackgroundBrush( QBrush(c) );
  119.  
  120. return t;
  121. }
  122.  
  123. /*!
  124.  * handle zoom events, especially reset zoom-base
  125.  * if back to initial zoom state
  126.  */
  127. void Zoomer::OnZoomed()
  128. {
  129. static int previousIndex = 0;
  130.  
  131. int index = this->zoomRectIndex();
  132.  
  133. debugZoomerStack();
  134.  
  135. // save startup scales
  136. // TODO: can not retrieve scales. Must be set externally
  137. if ((index == 0) && (previousIndex == 0)) {
  138. d->plotScaleX.enabled = plot->axisAutoScale(xAxis());
  139. d->plotScaleY.enabled = plot->axisAutoScale(yAxis());
  140. initScale();
  141. }
  142.  
  143. // only reset zoombase and replot if coming from
  144. // zoomed state and state is at the initual size
  145. if ((index == 0) && (previousIndex > 0)) {
  146.  
  147. if (!d->plotScaleX.enabled) {
  148. plot->setAxisAutoScale(xAxis());
  149. } else {
  150. plot->setAxisScale(xAxis(), d->plotScaleX.min, d->plotScaleX.max);
  151. }
  152.  
  153. if (!d->plotScaleY.enabled) {
  154. plot->setAxisAutoScale(QwtPlot::yLeft);
  155. plot->setAxisAutoScale(QwtPlot::yRight);
  156. } else {
  157. plot->setAxisScale(yAxis(), d->plotScaleY.min, d->plotScaleY.max);
  158. }
  159.  
  160. initScale();
  161. }
  162. previousIndex = index;
  163. }
  164.  
  165. void Zoomer::zoomOut()
  166. {
  167. this->zoom(-1);
  168. d->zoomerY2->zoom(-1);
  169. }
  170.  
  171. void Zoomer::zoomIn()
  172. {
  173. this->zoom(1);
  174. d->zoomerY2->zoom(1);
  175. }
  176.  
  177. void Zoomer::zoomBase()
  178. {
  179. this->zoom(0);
  180. d->zoomerY2->zoom(0);
  181. }
  182.  
  183.  
  184. void Zoomer::debugZoomerStack()
  185. {
  186. int index = this->zoomRectIndex();
  187. QStack<QwtDoubleRect> stack = this->zoomStack();
  188. QStack<QwtDoubleRect> stackY2 = d->zoomerY2->zoomStack();
  189. qDebug() << "--- Zoom Stack -----------------";
  190. for(int i = 0; i < stack.size(); ++i) {
  191. if (i == index) {
  192. qDebug() << i << "*, " << stack.at(i) << ", Y2: " << stackY2.at(i);
  193. } else {
  194. qDebug() << i << ", " << stack.at(i) << ", Y2: " << stackY2.at(i);
  195. }
  196. }
  197. }
To copy to clipboard, switch view to plain text mode 

Maybe my whole approach is wrong?
I do not know what really to debug.

Matthias