Hi,

we are using a QwtPlotScaleItem to display the axes' ticks inside of the canvas. And in our software the user has the option to switch between a linear and a logarithmic scale for each axis. I compressed our code to a minimum, so the bug is easier to reprocude. First, I derived from QwtPlot and create the QwtPlotScaleItem.

Plot.h
Qt Code:
  1. #include <qwt_plot.h>
  2.  
  3. enum class ScaleType
  4. {
  5. Linear,
  6. Logarithmic
  7. };
  8.  
  9.  
  10. class Plot : public QwtPlot
  11. {
  12. public:
  13. Plot();
  14.  
  15. void setScaleType(ScaleType scaleType);
  16.  
  17. private:
  18. ScaleType m_scaleType = ScaleType::Linear;
  19. QwtPlotScaleItem* m_scaleItem = nullptr;
  20.  
  21. void createScaleItem();
  22. };
To copy to clipboard, switch view to plain text mode 

Plot.cpp
Qt Code:
  1. #include "Plot.h"
  2. #include <QPen>
  3. #include <qwt_plot_grid.h>
  4. #include <qwt_plot_opengl_canvas.h>
  5. #include <qwt_scale_engine.h>
  6. #include <qwt_scale_widget.h>
  7. #include <qwt_plot_scaleitem.h>
  8.  
  9. Plot::Plot() : QwtPlot()
  10. {
  11. axisWidget(QwtPlot::xBottom)->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Ticks, false);
  12. axisWidget(QwtPlot::xBottom)->scaleDraw()->enableComponent(QwtAbstractScaleDraw::Backbone, false);
  13. createScaleItem();
  14. m_scaleItem->attach(this);
  15. setCanvas(new QwtPlotOpenGLCanvas());
  16. auto* grid = new QwtPlotGrid();
  17. grid->enableXMin(true);
  18. grid->enableYMin(true);
  19. grid->setMajorPen(QPen(Qt::black, 0, Qt::DotLine));
  20. grid->setMinorPen(QPen(Qt::gray, 0, Qt::DotLine));
  21. grid->attach(this);
  22. setAxisAutoScale(QwtPlot::xBottom, true);
  23. }
  24.  
  25. void Plot::setScaleType(ScaleType scaleType)
  26. {
  27. if (m_scaleType == scaleType)
  28. {
  29. return;
  30. }
  31. m_scaleType = scaleType;
  32. auto* scaleEngine = m_scaleType == ScaleType::Linear ?
  33. static_cast<QwtScaleEngine*>(new QwtLinearScaleEngine) :
  34. static_cast<QwtScaleEngine*>(new QwtLogScaleEngine);
  35.  
  36. const bool isFloatingEnabled = axisScaleEngine(QwtPlot::xBottom)->testAttribute(QwtScaleEngine::Floating);
  37. setAxisScaleEngine(QwtPlot::xBottom, scaleEngine);
  38. axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating, isFloatingEnabled);
  39. replot();
  40. }
  41.  
  42. void Plot::createScaleItem()
  43. {
  44. m_scaleItem = new QwtPlotScaleItem();
  45. m_scaleItem->setAlignment(QwtScaleDraw::TopScale);
  46. m_scaleItem->setXAxis(QwtPlot::xBottom);
  47. m_scaleItem->setScaleDivFromAxis(true);
  48. m_scaleItem->setFont(axisWidget(QwtPlot::xBottom)->font());
  49. m_scaleItem->setBorderDistance(0);
  50. auto* scaleDraw = m_scaleItem->scaleDraw();
  51. scaleDraw->enableComponent(QwtScaleDraw::Backbone, false);
  52. scaleDraw->enableComponent(QwtScaleDraw::Labels, false);
  53. scaleDraw->enableComponent(QwtScaleDraw::Ticks, true);
  54. }
To copy to clipboard, switch view to plain text mode 

In my dialog I am using the plot and define to buttons to switch between linear and logarithmic scale.
.h
Qt Code:
  1. #include "ui_QwtPlotClient.h"
  2.  
  3. class Plot;
  4.  
  5. class QwtPlotClient : public QDialog
  6. {
  7. Q_OBJECT
  8.  
  9. public:
  10. QwtPlotClient(QWidget* parent = nullptr);
  11.  
  12. private:
  13. Ui::QwtPlotClientClass m_ui;
  14. Plot* m_plot = nullptr;
  15. QwtPlotCurve* m_curve = nullptr;
  16. };
To copy to clipboard, switch view to plain text mode 

.cpp
Qt Code:
  1. #include "QwtPlotClient.h"
  2. #include "Plot.h"
  3. #include <qwt_plot_curve.h>
  4. #include <qwt_symbol.h>
  5. #include <QPushButton>
  6. #include <QSpacerItem>
  7.  
  8. namespace
  9. {
  10. const QVector<QPointF> linCurvePoints{ {-10, 10}, {20, 0}, {30, 20} , {40, -10} , {50, -5} };
  11. const QVector<QPointF> logCurvePoints{ {20, 0}, {30, 20} , {40, -10} , {50, -5} };
  12. }
  13.  
  14. QwtPlotClient::QwtPlotClient(QWidget* parent)
  15. : QDialog(parent),
  16. m_plot(new Plot()),
  17. m_curve(new QwtPlotCurve)
  18. {
  19. m_ui.setupUi(this);
  20. m_ui.plotFrame->layout()->addWidget(m_plot);
  21.  
  22. m_curve->setSamples(linCurvePoints);
  23. m_curve->setPen(Qt::red);
  24. m_curve->setSymbol(new QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::red), QPen(Qt::darkRed), QSize(8, 8)));
  25. m_curve->attach(m_plot);
  26.  
  27. auto* buttonLayout = new QHBoxLayout;
  28. m_ui.verticalLayout->addLayout(buttonLayout);
  29.  
  30. auto button = new QPushButton("Linear");
  31. connect(button, &QPushButton::clicked, this, [this]()
  32. {
  33. m_curve->setSamples(linCurvePoints);
  34. m_plot->setScaleType(ScaleType::Linear);
  35. });
  36. buttonLayout->addWidget(button);
  37.  
  38. button = new QPushButton("Log");
  39. connect(button, &QPushButton::clicked, this, [this]()
  40. {
  41. m_curve->setSamples(logCurvePoints);
  42. m_plot->setScaleType(ScaleType::Logarithmic);
  43. });
  44. buttonLayout->addWidget(button);
  45.  
  46. buttonLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Fixed));
  47. }
To copy to clipboard, switch view to plain text mode 

When I start the program, the ticks of the QwtPlotScaleItem are ok - they match perfectly with the grid.
Initial view.jpg

When I switch to the log scale, they are still perfectly matched to the grid.
LogScaleView.jpg

But when I now switch back to the linear scale, the (minor) ticks are off the grid.
LinearScaleViewAgain.jpg

When I resize the plot, everything looks good again. What am I missing or is this a bug?

Important to know: we are using Qt 5.14.0 and I tested this code with Qwt 6.2.0, 6.2.1 and 6.3.0.