Масштабировать ось X QChartView с помощью колесика мыши

В моем приложении я использую QChart для отображения линейного графика. К сожалению, Qt Charts не поддерживает такие базовые функции, как масштабирование колесиком мыши и прокрутка мышью. Да, есть функция RubberBand, но она по-прежнему не поддерживает прокрутку и т. д., что не так интуитивно понятно для пользователей. Также мне нужно масштабировать только ось X, что-то вроде setRubberBand(QChartView::HorizontalRubberBand), но с помощью колесика мыши. До сих пор, после погружения в QChartView, я использовал следующий обходной путь:

class ChartView : public QChartView {
protected:
    void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE
    {
        QRectF rect = chart()->plotArea();            
        if(event->angleDelta().y() > 0)
        {
            rect.setX(rect.x() + rect.width() / 4);
            rect.setWidth(rect.width() / 2);                                   
        }
        else
        {
            qreal adjustment = rect.width() / 2;
            rect.adjust(-adjustment, 0, adjustment, 0);                    
        }            
        chart()->zoomIn(rect);
        event->accept();            
        QChartView::wheelEvent(event);
    }
}

Это работает, но увеличение, а затем уменьшение масштаба не приводит к тому же результату. Есть небольшое отклонение. После отладки я обнаружил, что chart()->plotArea() всегда возвращает один и тот же прямоугольник, поэтому этот обходной путь бесполезен.

Есть ли способ получить только видимую область? Или, может быть, кто-нибудь может указать мне правильное решение, как масштабировать/прокручивать мышью для QChartView?


person folibis    schedule 05.02.2018    source источник


Ответы (2)


Вместо использования zoomIn() и zoomOut() вы можете использовать zoom(), как показано ниже:

class ChartView : public QChartView {
protected:
    void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE
    {
        qreal factor = event->angleDelta().y() > 0? 0.5: 2.0;
        chart()->zoom(factor);
        event->accept();
        QChartView::wheelEvent(event);
    }
};

По поводу zoomIn() и zoomOut() не понятно к каким координатам относится, я пока инвестирую, когда у меня будет больше информации я обновлю свой ответ.

обновление:

Как я наблюдаю, одна из проблем - это умножение чисел с плавающей запятой, а другая - найти центр фигуры, чтобы не было этих проблем, мое решение сбрасывает масштаб, а затем устанавливает изменение:

class ChartView : public QChartView {
    qreal mFactor=1.0;
protected:
    void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE
    {
        chart()->zoomReset();

        mFactor *= event->angleDelta().y() > 0 ? 0.5 : 2;

        QRectF rect = chart()->plotArea();
        QPointF c = chart()->plotArea().center();
        rect.setWidth(mFactor*rect.width());
        rect.moveCenter(c);
        chart()->zoomIn(rect);

        QChartView::wheelEvent(event);
    }
};
person eyllanesc    schedule 05.02.2018
comment
Спасибо за ответ. Я забыл заметить, мне нужно только масштабирование по оси x. Так что зум здесь не так удобен. Что-то вроде setRubberBand(QChartView::HorizontalRubberBand), но с колесиком мыши. - person folibis; 05.02.2018
comment
@folibis Я добавил новое решение. :D - person eyllanesc; 06.02.2018
comment
Хорошее решение, @eyllanesc! Спасибо! Это мне очень помогло. Другое решение, которое я нашел до сих пор, - это просто небольшая коррекция QChartPrivate::zoomIn(), т.е. удаление масштабирования по высоте, но для этого потребуется создать пользовательские классы, наследуемые от QChart. Ваше решение более элегантно. - person folibis; 06.02.2018

У меня это работает как для x, так и для масштабирования y со следующим кодом:

void wheelEvent(QWheelEvent *event){
qreal factor;
if ( event->delta() > 0 )
    factor = 2.0;
else
    factor = 0.5;

QRectF r = QRectF(chart()->plotArea().left(),chart()->plotArea().top(),
                                    chart()->plotArea().width()/factor,chart()->plotArea().height()/factor);
QPointF mousePos = mapFromGlobal(QCursor::pos());
r.moveCenter(mousePos);
chart()->zoomIn(r);
QPointF delta = chart()->plotArea().center() -mousePos;
chart()->scroll(delta.x(),-delta.y());}
person yonnak    schedule 02.07.2018