Альтернатива QwtPlotMarker
Изучаю библиотеку Qwt. Необходимо перемещать маркер динамически по пикселям (расчёт значения происходит в enableMagnifier). При попытке передвинуть текущий маркер по оси Х происходят рывки (их видно при масштабе для графика из 5000 точек, а также для большего масштаба, если масштаб уменьшить, появляется плавность хода маркера).
Подозреваю, что QwtPlotMarker не предназначен для динамического использования, либо я неправильно обновляю элементы на QwtPlot.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QToolBar>
#include <QToolButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
#include <QVector>
#include "math.h"
#include <qwt_counter.h>
#include <qwt_plot.h>
#include <qwt_plot_grid.h>
#include <qwt_legend.h>
#include <qwt_plot_curve.h>
#include <qwt_symbol.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_picker.h>
#include <qwt_picker_machine.h>
#include <qwt_plot_marker.h>
#include <qwt_scale_div.h>
#include <qwt_column_symbol.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QwtPlot *d_plot;
void setPlot();
QwtPlotGrid *grid;
void setPlotGrid();
QwtPlotCurve *curve;
void setCurveParameters();
QPolygonF points;
QVector<double> dVecPointsY;
QVector<double> dVecPointsX;
void addPointsToCurveAndShow();
QwtPlotMagnifier *magnifier;
void enableMagnifier();
QwtPlotPanner *d_panner;
void enableMovingOnPlot();
QwtPlotPicker *d_picker;
void enablePicker();
QToolBar *toolBar;
void setToolBar();
double changeXValue;
QPushButton *choiceMarkerButton;
void addChoiceMarkerButton();
QPushButton *changeStepButton;
void addChangeStepButton();
QPushButton *moveMarkerButton;
void addMoveMarkerButton();
QwtPlotMarker *markerA;
QwtPlotMarker *markerB;
double dPositionMarkerA = 0;
double dPositionMarkerB = 0;
int iCurrentMarker = 0;
double dCurrentStep;
QVector <QwtPlotMarker*> vecMarkers;
QVector <double> dVecPosition;
private Q_SLOTS:
void click_on_canvas(const QPoint &pos);
void choiceMarker();
void moveMarker();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setPlot();
setPlotGrid();
setCurveParameters();
addPointsToCurveAndShow();
enableMagnifier();
enableMovingOnPlot();
enablePicker();
connect( d_picker, SIGNAL( appended( const QPoint & ) ),
SLOT( click_on_canvas( const QPoint & ) ) );
setToolBar();
dVecPosition.append(dPositionMarkerA);
dVecPosition.append(dPositionMarkerB);
markerA = new QwtPlotMarker();
markerA->setLineStyle(QwtPlotMarker::VLine);
markerA->setLinePen(Qt::black, 2, Qt::SolidLine);
markerA->setXValue(dVecPosition[iCurrentMarker]);
markerA->attach(d_plot);
markerB = new QwtPlotMarker();
markerB->setLineStyle(QwtPlotMarker::VLine);
markerB->setLinePen(Qt::red, 2, Qt::SolidLine);
markerB->setXValue(dVecPosition[iCurrentMarker]);
markerB->attach(d_plot);
vecMarkers.append(markerA);
vecMarkers.append(markerB);
addChoiceMarkerButton();
addMoveMarkerButton();
connect(choiceMarkerButton, SIGNAL(clicked()), SLOT(choiceMarker()));
connect(moveMarkerButton, SIGNAL(clicked()), SLOT(moveMarker()));
}
void MainWindow::choiceMarker() {
qDebug() << "choice";
if(iCurrentMarker == 0)
++iCurrentMarker;
else
--iCurrentMarker;
}
void MainWindow::addChoiceMarkerButton()
{
choiceMarkerButton = new QPushButton("ChoiceMarker");
toolBar->addWidget(choiceMarkerButton);
}
void MainWindow::addMoveMarkerButton() {
moveMarkerButton = new QPushButton("Move");
moveMarkerButton->setAutoRepeatInterval(0);
moveMarkerButton->setAutoRepeat(true);
toolBar->addWidget(moveMarkerButton);
}
void MainWindow::moveMarker() {
//dCurrentStep = setterStep->value();
vecMarkers.at(iCurrentMarker)->setXValue(vecMarkers.at(iCurrentMarker)->xValue() + dCurrentStep);
qDebug() << "dCurrentStep: " << dCurrentStep;
}
void MainWindow::setToolBar()
{
toolBar = new QToolBar( this );
addToolBar(toolBar);
}
void MainWindow::setPlot()
{
d_plot = new QwtPlot( this );
d_plot->setAutoReplot(true);
setCentralWidget(d_plot);
d_plot->setTitle("Qwt demonstration");
d_plot->setCanvasBackground( Qt::white );
d_plot->setAxisTitle(QwtPlot::yLeft, "Y");
d_plot->setAxisScale(QwtPlot::yLeft, 0,0.01);
d_plot->setAxisTitle(QwtPlot::xBottom, "X");
d_plot->insertLegend( new QwtLegend() );
}
void MainWindow::setPlotGrid()
{
grid = new QwtPlotGrid();
grid->setMajorPen(QPen( Qt::gray, 2 ));
grid->attach( d_plot );
}
void MainWindow::setCurveParameters()
{
curve = new QwtPlotCurve();
curve->setPen( Qt::blue, 6 );
curve->setRenderHint
( QwtPlotItem::RenderAntialiased, true );
}
void MainWindow::addPointsToCurveAndShow()
{
for(int i = 0; i < 5000; i++) {
dVecPointsY.append(qSin(i) / i);
}
for (int i = 0; i < 5000; i++) {
points << QPointF(i, dVecPointsY.at(i));
}
curve->setSamples(points);
curve->attach( d_plot );
}
void MainWindow::enableMagnifier()
{
magnifier = new QwtPlotMagnifier(d_plot->canvas());
magnifier->setMouseButton(Qt::MidButton);
dCurrentStep = qAbs(d_plot->axisInterval(QwtPlot::xBottom).maxValue() - d_plot->axisInterval(QwtPlot::xBottom).minValue()) / d_plot->sizeHint().rwidth();
}
void MainWindow::enableMovingOnPlot()
{
d_panner = new QwtPlotPanner( d_plot->canvas() );
d_panner->setMouseButton( Qt::RightButton );
}
void MainWindow::enablePicker()
{
d_picker =
new QwtPlotPicker(
QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand,
QwtPicker::AlwaysOn,
d_plot->canvas() );
d_picker->setRubberBandPen( QColor( Qt::red ) );
d_picker->setTrackerPen( QColor( Qt::black ) );
d_picker->setStateMachine( new QwtPickerDragPointMachine() );
}
void MainWindow::click_on_canvas(const QPoint &pos)
{
double x = d_plot->invTransform(QwtPlot::xBottom, pos.x());
double y = d_plot->invTransform(QwtPlot::yLeft, pos.y());
QString info = "x= " + QString::number(x) +
"; y = " + QString::number(y);
statusBar()->showMessage(info);
}
MainWindow::~MainWindow()
{
delete ui;
}