QCustomPlot Discussion and Comments

Drag a curveReturn to overview

Hello, I am trying to move a closed polygon represented by a QCPCurve when user click ont it in combination with CTRL key. The curve is intented to follow the mouse while mouse button is maintained pressed. Code is quite working, however, curve moves faster than mouse. I've looked at functions like mapToGlobal/mapFromGlobal without success. Could you help me ? Thanks !

Private members in class:

    QCustomPlot * plot = nullptr;
    QCPCurve * curve = nullptr;
    bool m_dragging = false;
    QPoint m_origin;

Code:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    plot = new QCustomPlot(this);
    curve = new QCPCurve(plot->xAxis, plot->yAxis);

    connect(plot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(myClick(QMouseEvent*)));
    connect(plot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(myDrag(QMouseEvent*)));
    connect(plot, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(myRelease(QMouseEvent*)));
}

void MainWindow::myClick(QMouseEvent * mouse) {
    if((mouse->modifiers() & Qt::ControlModifier) && curve->selectTest(mouse->pos(), true)<plot->selectionTolerance()) {
        m_dragging = true;
        m_origin = mouse->pos();
    }
}

void MainWindow::myDrag(QMouseEvent * mouse) {

    if(m_dragging) {
        QPoint shift = mouse->pos()-m_origin;
        for(auto it=curve->data().data()->begin(); it!=curve->data().data()->end(); ++it) {
            it->key += shift.x();
            it->value -= shift.y();
        }
        m_origin = mouse->pos();
        plot->replot();
    }
}

void MainWindow::myRelease(QMouseEvent * mouse) {
    Q_UNUSED(mouse);
    m_dragging = false;
}

mouse->pos() is in pixel coordinates. Qt mapToGlobal takes a point in object coordinate system and converts it to global position... i.e pixel 0,0 in the objec coordinate is top left of the object, but in the global coordinate system it might be pixel 340,350 or something. This is not what you want.

You dont have written in your code how you are actually using m_origin to move the curve, but my guess is you want to be using QCPAxis::pixelToCoord instead of mapToGlobal.

Thanks Ian, I have used QCPAxis::pixelToCoord and it works very well. Here is my updated code. m_origin is used in my drag function like what follows:

void MainWindow::myDrag(QMouseEvent * mouse) {
    if(m_dragging) {
        QCPCurveDataContainer * container = curve->data().data();
        for(auto it=container->begin(); it!=container->end(); ++it) {
            it->key += plot->xAxis->pixelToCoord(mouse->pos().x())-plot->xAxis->pixelToCoord(m_origin.x());
            it->value += plot->yAxis->pixelToCoord(mouse->pos().y())-plot->yAxis->pixelToCoord(m_origin.y());
        }
        plot->replot();
        m_origin = mouse->pos();
    }
}