Search code examples
c++qtqtcharts

qt chart move view with pressed middle mouse button


I'm currently working with Qts Chart plotting tool. I have now a plot where I can zoom in and out by using the chartview class provieded by this example (with small adjustments). I would like to see the ability to not only zoom, but also move my view a pressed middle mouse button (which is used a lot in other applications and therefore is very intuitive).

How can I do this in Qt? How can I check if a middle mouse button is pressed and released and change my view at the plot if the mouse moves during a pressed middle mouse button...

I'm sure someone has coded this before and would really appreciate a small example/help.


Solution

  • you need to derive a class from QChartView and overload the mouse events:

    class ChartView: public QChartView
    {
        Q_OBJECT
    
    public:
        ChartView(Chart* chart, QWidget *parent = 0);
    
    protected:
    
        virtual void mousePressEvent(QMouseEvent *event) override;
        virtual void mouseMoveEvent(QMouseEvent *event) override;
    
    private:
    
        QPointF m_lastMousePos;
    };
    
    ChartView::ChartView(Chart* chart, QWidget *parent)
        : QChartView(chart, parent)
    {
        setDragMode(QGraphicsView::NoDrag);
        this->setMouseTracking(true);
    }
    
    void ChartView::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::MiddleButton)
        {
            QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor));
            m_lastMousePos = event->pos();
            event->accept();
        }
    
        QChartView::mousePressEvent(event);
    }
    
    void ChartView::mouseMoveEvent(QMouseEvent *event)
    {
        // pan the chart with a middle mouse drag
        if (event->buttons() & Qt::MiddleButton)
        {
            QRectF bounds = QRectF(0,0,0,0);
            for(auto series : this->chart()->series())
                bounds.united(series->bounds())
    
            auto dPos = this->chart()->mapToValue(event->pos()) - this->chart()->mapToValue(m_lastMousePos);
    
            if (this->rubberBand() == QChartView::RectangleRubberBand)
                this->chart()->zoom(bounds.translated(-dPos.x(), -dPos.y()));
            else if (this->rubberBand() == QChartView::HorizontalRubberBand)
                this->chart()->zoom(bounds.translated(-dPos.x(), 0));
            else if (this->rubberBand() == QChartView::VerticalRubberBand)
                this->chart()->zoom(bounds.translated(0, -dPos.y()));
    
            m_lastMousePos = event->pos();
            event->accept();
        }
    
        QChartView::mouseMoveEvent(event);
    }