Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据

这篇具有很好参考价值的文章主要介绍了Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        说在前面,本人也是近段时间刚开始学习Qt,实现上述功能的方法可能并不是最优,写此篇文章也是记录下学习的过程,也与大家分享一下。(在此先描述,后面会附上代码)(前面说的会比较基础)

        首先,要使用QChartView类得现在.pro文件中加入:(得确保你的Qt中有QtCharts,可以在qt文件夹下Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据include文件夹中查看)

QT       += charts

         同时需要在所创建的主窗口的.h文件下加入:

QT_BEGIN_NAMESPACE
class QChartView;
class QChart;
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

        由于Qt6与Qt5中有些不太一样,NAMESPACE的使用方式也有所更改,所以不同的版本得按不同的规则来。(后面对坐标轴的建立及使用也有不一样的地方)

        然后在ui设计界面拖入QGraphicsView并将其提升为QChartView,或是自建类。(本人所采用的是自建类的方式,所以本文主要按自建类的方式来说明。特别强调下,自建类更方便采用鼠标事件,建议使用自建类,自建类继承QChartView即可)

        本文自建类的名称为chartview,如果没建立则基类选择QGraphics,提升的类名写自建类的名称即可。

Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据

 

        最后在头文件中加入:(其实没啥先后顺序,都执行就行0.0)

#include <QtCharts>

        就应该可以开始建立波形图了。建立方法如下:

        首先先创建一个新的QChart指针、所需要画的线的指针(折线为QLineSeries,曲线为

QSplineSeries,散点为QScatterSeries)与坐标系指针。
    QSplineSeries* line;
    QChart* chart;
    QValueAxis *axisX;
    QValueAxis *axisY;

        弄完这些就可以直接创建了图了:

        QPen pen;
        pen.setWidth(1);
        pen.setColor(QColor(21, 100, 255));
        m_Timer = new QTimer(this);

        connect(m_Timer,SIGNAL(timeout()),this,SLOT(updata_plot())); 

        line = new QSplineSeries(this);

        chart = new QChart();
        chart->addSeries(line);
        axisX = new QValueAxis(this);
        axisY = new QValueAxis(this);

    //     line->setName("");//设置曲线名称
        line->setPen(pen);//设置曲线颜色                   
        line->setMarkerSize(2); //点大小
        line->setUseOpenGL(true);//openGl 加速

    //    chart->setTitle("Pressure Data");//设置图标标题
        chart->removeSeries(line);
        chart->addSeries(line);

        chart->addAxis(axisX,Qt::AlignBottom);
        chart->addAxis(axisY,Qt::AlignLeft);
        axisX->setRange(0,100);
        axisY->setRange(0,10);
        axisX->setLabelFormat("%.1f");

        line->attachAxis(axisX);
        line->attachAxis(axisY);
        line->setPointsVisible(true);
        ui->"这里是你创建的QChartView对象名"->setChart(chart);

        大致创建就说到这里,主要还是说鼠标事件。

        由于是自建类,不好调用ui(如果硬要调用也是可以的,但操作比较麻烦,不推荐)

        简单做法就是直接信号与槽,即chartview下的鼠标事件发生后发送一个信号连接MainWindow下的槽函数,然后再槽函数中处理。(这里先附代码,再说方法)

        chartview.h

#ifndef CHARTVIEW_H
#define CHARTVIEW_H

#include <QGraphicsView>
#include <QMouseEvent>
#include <QChartView>
#include <QWheelEvent>

class chartview : public QChartView
{
    Q_OBJECT
public:
    explicit chartview(QWidget *parent = nullptr);

signals:

    void sendevent(QMouseEvent *ev);
    void wheelevent(QWheelEvent *ev);
    void relaeseevent(QMouseEvent *ev);

private slots:

    void mouseMoveEvent(QMouseEvent *ev); //鼠标移动事件
    void wheelEvent(QWheelEvent *ev);     //鼠标滚动事件
    void mouseReleaseEvent(QMouseEvent *ev);//鼠标释放事件
};

#endif // CHARTVIEW_H

        chartview.c

#include "chartview.h"
#include <QDebug>

chartview::chartview(QWidget *parent)
    : QChartView{parent}
{

}

void chartview::mouseMoveEvent(QMouseEvent *ev)
{

    emit sendevent(ev);

}

void chartview::wheelEvent(QWheelEvent *ev)
{

    emit wheelevent(ev);

}

void chartview::mouseReleaseEvent(QMouseEvent *ev)
{

     emit relaeseevent(ev);

}

        mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QtCharts>
#include <QTimer>
#include <QList>
#include <QWheelEvent>
#include <QMouseEvent>

QT_BEGIN_NAMESPACE
class QChartView;
class QChart;
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QTimer* m_Timer;
    QLabel *label;
    QSplineSeries* line;
    QVector<QPointF> MV_reserve;
    int max_reserve =1000;
    //绘图变量与坐标
    QChart* chart;
    QValueAxis *axisX;
    QValueAxis *axisY;
    void creat_chartview(); //创建图表视图

public slots:

    void updata_plot();    //更新图标视图
    void chartmove(QMouseEvent *ev);
    void wheelmove(QWheelEvent *ev);
    void releasemove(QMouseEvent *ev);
private slots:
    void on_pushButton_clicked();
};
#endif // MAINWINDOW_H

        mainwindow.c

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "chartview.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_Timer = new QTimer(this);
    m_Timer->start(10);
    m_Timer->stop();
    label = new QLabel(this);
    label->setStyleSheet(QString("QLabel{color:#1564FF; font-family:\"Microsoft Yahei\"; font-size:10px; font-weight:bold;"
                                        " background-color:rgba(21, 100, 255, 51); border-radius:4px; text-align:center;}"));
    label->setFixedSize(58, 24);
    label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    label->hide();
    creat_chartview();
    connect(ui->ShowChart0,&chartview::sendevent,this,&MainWindow::chartmove);     //左键拖动右键拖动与悬浮
    connect(ui->ShowChart0,&chartview::wheelevent,this,&MainWindow::wheelmove);    //滚动
    connect(ui->ShowChart0,&chartview::relaeseevent,this,&MainWindow::releasemove);//中键按下
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::creat_chartview()
{
        QPen pen;
        pen.setWidth(1);
        pen.setColor(QColor(21, 100, 255));
        connect(m_Timer,SIGNAL(timeout()),this,SLOT(updata_plot()));

        line = new QSplineSeries(this);

        chart = new QChart();
        chart->addSeries(line);
        axisX = new QValueAxis(this);
        axisY = new QValueAxis(this);

//        line->setName("");//设置曲线名称
        line->setPen(pen);//设置曲线颜色                   
        line->setMarkerSize(2);//点大小
        line->setUseOpenGL(true);//openGl 加速

        chart->removeSeries(line);
        chart->addSeries(line);

        chart->addAxis(axisX,Qt::AlignBottom);
        chart->addAxis(axisY,Qt::AlignLeft);
        axisX->setRange(0,100);
        axisY->setRange(0,10);
        axisX->setLabelFormat("%.1f");

        line->attachAxis(axisX);
        line->attachAxis(axisY);
        line->setPointsVisible(true);
        ui->ShowChart0->setChart(chart);

}
void MainWindow::updata_plot()
{
    double left,right,err;
        QVector<QPointF> newlist;
        left = axisX->min();
        right= axisX->max();
        err=right-left;
        MV_reserve = line->points();
//        qDebug()<<MV_reserve.size();
        if(MV_reserve.size() == max_reserve)
        {
            for(int i =1 ; i<max_reserve ;i++)
            {
                newlist.append(QPointF(i-1,MV_reserve.at(i).y()));
            }
        }
        else
        {
            newlist = MV_reserve;
            if(MV_reserve.size()>=right)
            {
                axisX->setRange(MV_reserve.size()-err,MV_reserve.size());
            }
        }
        newlist.append(QPointF(MV_reserve.size(),rand()%10));
        line->replace(newlist);
}

void MainWindow::wheelmove(QWheelEvent *ev)      //鼠标滚动放大缩小指向区域
{
    QPoint sroll = ev->angleDelta();
    if(ev->position().x()>=60&&ev->position().x()<=ui->ShowChart0->width()-40
        &&ev->position().y()>=80&&ev->position().y()<=ui->ShowChart0->height()-50)
    {
        double left,right,err;
        double Currentpoint,changer,changel;

        left = axisX->min();
        right= axisX->max();
        err=right-left;
        Currentpoint = ((ev->position().x()-60)/(ui->ShowChart0->width()-100))*err+left;

        if(sroll.y() > 0)
        {
            if(err>=10)
            {
                changer = right-(right-Currentpoint)*0.1;
                changel = left+(Currentpoint-left)*0.1;
                axisX->setRange(changel,changer);
            }
        }
        else
        {
            changer = right+(right-Currentpoint)*0.1;
            changel = left-(Currentpoint-left)*0.1;
            if(changer>=MV_reserve.size()) {changer=MV_reserve.size();}
            if(changel<=0)                 {changel=0;  }
            axisX->setRange(changel,changer);
        }
    }
}

void MainWindow::chartmove(QMouseEvent *ev)         //鼠标左键点击拖动图片右键拖动缩放相关坐标轴
{
    static QPoint last_posl,last_posr;

    QPoint changepos;
    QPoint now_pos;

    double err,erry,left,right,height,bottom;
    left = axisX->min();
    right = axisX->max();
    height = axisY->max();
    bottom = axisY->min();
    err = right-left;
    erry = height-bottom;
    if(ev->position().x()>=60&&ev->position().x()<=ui->ShowChart0->width()-40
        &&ev->position().y()>=80&&ev->position().y()<=ui->ShowChart0->height()-50)//鼠标悬停
    {
        double nearposx,posy,posx,poserrx;
        int selectx;
        nearposx = left + (ev->position().x()-60)/(ui->ShowChart0->width()-100)*err;
        //判断当前距离最近的一个点
        if(int(nearposx*10)%10<5)
        {
            selectx = int(nearposx);
        }
        else
        {
            selectx = int(nearposx+1);
        }
        //求出一个比较好的范围
        poserrx = (ui->ShowChart0->width()-100)/err;
        if(poserrx<20)
        {
            poserrx/=2;
        }
        else
        {
            poserrx=10;
        }
        //判断该点是否在图中
        if(line->at(selectx).y()<height+err*0.01)
        {
            posx = 60+((line->at(selectx).x()-left)/err)*(ui->ShowChart0->width()-100);
            posy = 80+((height - line->at(selectx).y())/erry)*(ui->ShowChart0->height()-130);
            if(ev->position().y()<=(posy+10)&&ev->position().y()>=(posy-10)
                &&ev->position().x()<=(posx+poserrx)&&ev->position().x()>=(posx-poserrx))
            {
                label->setText(QString::asprintf("(%.1f,%d)", line->at(selectx).y(),(int)line->at(selectx).x()));
                label->move(ev->position().x() +133, ev->position().y() +43);
                label->show();
                //在这生成一个qlabel
            }
            else
            {
                label->hide();
                //在这隐藏生成的qlabel
            }
        }


    if(MV_reserve.size()>=100&&ev->buttons()==Qt::LeftButton)  左键拖动
    {
        now_pos = ev->pos();
        changepos = now_pos-last_posl;
        last_posl = now_pos;
        if(axisX->min()<=0&&changepos.x()>0)
        {
            axisX->setRange(0,err);
            return;
        }
        else if(axisX->max()>=MV_reserve.size()-1&&changepos.x()<0)
        {
            axisX->setRange(MV_reserve.size()-err,MV_reserve.size());
            return;
        }
        else
        {
            chart->scroll(-changepos.x(),changepos.y());
        }
    }
    else
    {
        last_posl = ev->pos();
    }

    if(ev->buttons()==Qt::RightButton)         右键拖动
        {
            double changel,changer,changeh,changeb;
            now_pos = ev->pos();
            changepos = now_pos-last_posr;
            last_posr = now_pos;

            if(changepos.x()>0)
            {
                changel = left+err*0.01*changepos.x();
                changer = right-err*0.01*changepos.x();
                if((changer-changel)>=5)
                {
                    axisX->setRange(left+err*0.01*changepos.x(),right-err*0.01*changepos.x());
                }
            }
            else if(changepos.x()<0)
            {
                changel = left+err*0.01*changepos.x();
                changer = right-err*0.01*changepos.x();
                if(changel>=0&&changer<=MV_reserve.size())
                {
                    axisX->setRange(changel,changer);
                }
                else
                {
                    if(changel<0&&changer<=MV_reserve.size())
                    {
                        axisX->setRange(0,changer);
                    }
                    else if(changel>=0&&changer>MV_reserve.size())
                    {
                        axisX->setRange(changel,MV_reserve.size());
                    }
                    else
                    {
                        axisX->setRange(0,MV_reserve.size());
                    }
                }
            }
            if(changepos.y()>0)
            {
                changeh = height+erry*0.01*changepos.y();
                changeb = bottom-erry*0.01*changepos.y();
                axisY->setRange(changeb,changeh);

            }
            else if(changepos.y()<0)
            {
                changeh = height+erry*0.01*changepos.y();
                changeb = bottom-erry*0.01*changepos.y();
                axisY->setRange(changeb,changeh);
            }
        }
    else
        {
            last_posr = ev->pos();
        }
    }


}

void MainWindow::releasemove(QMouseEvent *ev)    鼠标中键点击缩小
{

    if(ev->button()==Qt::MiddleButton
        &&ev->position().x()>=70&&ev->position().x()<=ui->ShowChart0->width()-50
        &&ev->position().y()>=90&&ev->position().y()<=ui->ShowChart0->height()-60)
    {
        double errx,leftx,rightx;
        double erry,lefty,righty;

        leftx = axisX->min();
        rightx = axisX->max();
        errx = rightx-leftx;

        lefty = axisY->min();
        righty = axisY->max();
        erry = righty-lefty;

        leftx-=errx*0.4;
        rightx+=errx*0.4;

        lefty-=erry*0.4;
        righty+=erry*0.4;

        if(leftx>=0&&rightx<=MV_reserve.size())
        {axisX->setRange(leftx,rightx);}
        else
        {
            if(leftx<=0&&rightx>=MV_reserve.size())
            {axisX->setRange(0,MV_reserve.size());}
            else if(leftx<=0)
            {axisX->setRange(0,rightx);}
            else
            {axisX->setRange(leftx,MV_reserve.size());}
        }
        axisY->setRange(lefty,righty);

    }

}


void MainWindow::on_pushButton_clicked()
{
    if(m_Timer->isActive())
    {
        m_Timer->stop();
    }
    else
    {
        m_Timer->start();
    }
}

        左右键与悬停显示都是基于mousemoveevent,左键平移好理解,右键缩放也应该没啥问题,里面主要是对悬停比较麻烦,按理说应该可以用点的hover信号,但不知道为啥,这个信号的好像没那么稳定,所以只能自己写,大致就是先判断距离最近的点,再在该点周围画个框,判断鼠标是否在这个框里面,如果在,就show创建的label,不在就hide创建的label。

附上网盘:

链接:https://pan.baidu.com/s/1CFOA82rWkepk3-tFQ2u4Cg 
提取码:g2uh文章来源地址https://www.toymoban.com/news/detail-491188.html

到了这里,关于Qt6使用QChartView类与鼠标事件实现波形的缩放、平移、坐标轴单轴缩放与鼠标悬停显示点的数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt实现鼠标双击事件

    当同一个部件既要响应鼠标单击事件又要响应鼠标双击事件时,就会发生冲突,如下例: 创建自己的按钮类,让其继承于QPushButton类 (特别注意!!!) ,在创建类的时候默认可供选择的基类中无QPushButton类且没有QPushButton类的基类,无法使用多重继承,故必须手动修改继承

    2024年02月10日
    浏览(32)
  • QT的使用3:鼠标事件

    用户对界面中的控件进行操作后,控件需要进行响应,响应一般有两种方式,一种是之前学过的槽函数,另一种是事件,部分操作无法通过槽函数响应,只能通过事件,例如鼠标移动,键盘输入等。 当某个事件(鼠标、键盘)发生的时候,相关控件就会收到这个事件,并且调

    2024年02月13日
    浏览(30)
  • QT--day4(定时器事件、鼠标事件、键盘事件、绘制事件、实现画板、QT实现TCP服务器)

     QT实现tcpf服务器代码:(源文件) 头文件:

    2024年02月15日
    浏览(39)
  • 自定义QChartView实现鼠标放在图表时,显示鼠标位置坐标值(x,y)

    前言: 因为需要一次性从文件中加载大量数据到图表中显示,所以打算使用qchartview+qscrollarea,当横坐标数据超出默认设定的显示范围之后,重新设置chartview的宽度和scrollarea内容区域(scrollAreaWidgetContents)的宽度,从而实现一次性显示所有数据的目的。因为这样显示之后,如果

    2024年02月05日
    浏览(31)
  • Qt实现全局鼠标事件监听器-Windows

    更多精彩内容 👉个人内容分类汇总 👈 👉Qt自定义模块、工具👈 Qt版本:V5.12.5 兼容系统: Windows:这里测试了Windows10,其它的版本没有测试; Linux:这里测试了ubuntu18.04、20.04,其它的没有测试; Mac:等啥时候我有了Mac电脑再说。 有时候我们想获取到【系统全局鼠标事件】

    2024年02月16日
    浏览(28)
  • Qt实现全局鼠标事件监听器-Linux

    更多精彩内容 👉个人内容分类汇总 👈 👉Qt自定义模块、工具👈 Qt版本:V5.12.5 兼容系统: Windows:这里测试了Windows10,其它的版本没有测试; Linux:这里测试了ubuntu18.04、20.04,其它的没有测试; Mac:等啥时候我有了Mac电脑再说。 有时候我们想获取到【系统全局鼠标事件】

    2024年02月11日
    浏览(30)
  • Python Qt6快速入门-事件处理

    Qt GUI应用程序的核心是 QApplication 类。 每个GUI应用程序都需要一个并且只有一个 QApplication 对象才能运行。 该对象包含应用程序的事件循环——控制所有用户与 GUI 交互的核心循环。

    2024年02月15日
    浏览(32)
  • QTday4(鼠标事件和键盘事件/QT实现连接TCP协议)

    笔记 时钟绘制  

    2024年02月15日
    浏览(24)
  • Qt之事件过滤器讲解并且实现快捷键切换鼠标焦点

    现在有一个类似于下方图的ui,用户需要在输入前一行内容后,需要摁下指定案件能够跳转到下一行继续进行输入。 一种更为直接的解决方案是子类化 QLineEdit 并且重新实现鼠标事件 keyPressEvent() ,然后调用 focusNextChild() 。 首先需要创建一个子类MyLineEdit继承于QLineEdit类。然后重

    2024年02月12日
    浏览(36)
  • 【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件

    说明 在使用Qt的图形视图框架实现功能时,一般会在其基础上进行自定义功能实现。 如:滚轮对场景的缩放,鼠标拖动场景中的项,以及可以在场景中进行右键操作等。 示例 myitem 为自定义QGraphicsItem,实现了边框、重绘事件、鼠标悬停、按键、右键菜单等功能。 myitem.h myi

    2024年02月04日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包