原创 QT 折线图增加鼠标操作功能

2023-11-17 15:39 1357 2 2 分类: MCU/ 嵌入式 文集: QT学习

QGraphicsView 本身并没有鼠标操作功能。需要另写函数实现。基本的思路是写一个新的类,继承QGraphicsView

class ChartView : public QChartView 

再重载鼠标操作函数。

void mousePressEvent(QMouseEvent *event) override

void mouseMoveEvent(QMouseEvent *event) override

void mouseReleaseEvent(QMouseEvent *event) override

void wheelEvent(QWheelEvent *event) override

需要使用3个私有的变量记录鼠标的动作状态

private:

    bool isClicking;    //记录鼠标左键按下和释放,只有在按下鼠标再拖动时才产生动作。

    int startX;        // 记录鼠标按下时起始点位置

    int startY;

使用两个公共指针,指向序列数据和折线图

public:

    QLineSeries *series;       // 用于折线图的数据序列

    QChart *chart;            //  图指针

 

在鼠标左键按下的事件处理函数中使 isClicking true,同时使用StartX StartY 记录起始点位置

在鼠标左键释放的事件处理函数中使用isClicking false

在鼠标移动事件中,获取移动的距离,改变数轴的范围。这样就可以实现鼠标点击拖动。

在鼠标滚轮滚动的事件中,获取滚轮滚动量和方向,同步改变数轴的范围,实现图片左右移动。

 

生成一个 chartview.h 文件,并添加到工程中。

#ifndef CHARTVIEW_H

#define CHARTVIEW_H

#include <QApplication>

#include <QtCharts>

#include <QLineSeries>

#include <QChart>

#include <QChartView>

#include <QValueAxis>

#include <QMouseEvent>

 

QT_CHARTS_USE_NAMESPACE

 

class ChartView : public QChartView

{

public:

    QLineSeries *series;

    QChart *chart;

    ChartView(QWidget *parent = nullptr) : QChartView(parent), isClicking(false)

    {

        // 创建折线图

        series = new QLineSeries();

        series->append(-3, 4);

        series->append(-2, 3);

        series->append(-1, 2);

        series->append(0, 1);

        series->append(1, 3);

        series->append(2, 2);

        series->append(3, 4);

 

        chart = new QChart();

        chart->addSeries(series);

        chart->createDefaultAxes();

        chart->legend()->hide();

 

        setChart(chart);

        setRenderHint(QPainter::Antialiasing);

        setRubberBand(QChartView::RectangleRubberBand);

    }

 

protected:

    void mousePressEvent(QMouseEvent *event) override

    {

        if (event->button() == Qt::LeftButton)

        {

            isClicking = true;

            startX = event->x();

            startY = event->y();

        }

    }

 

    void mouseMoveEvent(QMouseEvent *event) override

    {

        if (isClicking)

        {

            int deltaX = event->x() - startX;

            int deltaY = event->y() - startY;

//            QChart *chart = this->chart();

            if (event->modifiers() == Qt::ControlModifier)

            {

                QValueAxis *axisX = qobject_cast<QValueAxis *>(chart->axes(Qt::Horizontal).at(0));

                QValueAxis *axisY = qobject_cast<QValueAxis *>(chart->axes(Qt::Vertical).at(0));

                if (axisX && axisY)

                {

                    qreal deltaXRatio = deltaX / chart->plotArea().width();

                    qreal deltaYRatio = deltaY / chart->plotArea().height();

                    qreal deltaXValue = deltaXRatio * (axisX->max() - axisX->min());

                    qreal deltaYValue = deltaYRatio * (axisY->max() - axisY->min());

                    axisX->setRange(axisX->min() - deltaXValue, axisX->max() - deltaXValue);

//                  axisY->setRange(axisY->min() + deltaYValue, axisY->max() + deltaYValue);

                }

            }

            else

            {

                chart->scroll(-deltaX, deltaY);

            }

            startX = event->x();

            startY = event->y();

        }

    }

 

    void mouseReleaseEvent(QMouseEvent *event) override

    {

        if (event->button() == Qt::LeftButton)

        {

            isClicking = false;

        }

    }

 

    void virtual wheelEvent(QWheelEvent *event) override{

        qreal temp = event->angleDelta().y();

        QValueAxis *axisX = qobject_cast<QValueAxis *>(chart->axes(Qt::Horizontal).at(0));

        if(temp>0)

            axisX->setRange(axisX->min() + 1 , axisX->max() + 1);

        else

            axisX->setRange(axisX->min() - 1 , axisX->max() - 1);

    }

private:

    bool isClicking;

    int startX;

    int startY;

};

#endif // CHARTVIEW_H

 

 

在窗口中增加一个Graphics view 控制,并提升为这个扩展的类。

现在这个折线图就可以使用鼠标操作了。

 

因为这个类中有公有的  QLineSeries 指针,在获取指针后可以对数据序列进行操作。

void MainWindow::on_pushButton_clicked()

{

    static int i = 7;

    QLineSeries *p;

    p = ui->graphicsView->series;  // 获取数据序列指针

    p->append(i,3);

    i++;

}

测试一下:


作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

给作者打赏,鼓励TA抓紧创作!

赞赏支持
点赞 2
赞赏0

文章评论0条评论)

登录后参与讨论
我要评论
0
2
1
2
3
4
5
6
7
8
9
0
关闭 站长推荐上一条 /4 下一条