学习日记4:qt实现多条曲线绘制,右击选中可选择隐藏或显示

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


成果展示

在这里插入图片描述

本文绘图用到customplot类,主要实现了以下功能:

 1、曲线绘制
 2、选中图例或图线实现隐藏、显示
 3、滑动条的实现

准备工作

1、将以下四个文件复制到自己的工程目录下

在这里插入图片描述
2、将文件在项目头文件和源文件中分别添加
在这里插入图片描述

3、将widget窗口提升为QCustomPlot类,当右侧基类显示为QCustomPlot类,说明提升成功
在这里插入图片描述

主要代码

1、初始化

void MainWindow::Init()  //初始化
{
    ui->horizontalScrollBar->setRange(0,1000); //设置滑动条的范围
    ui->verticalScrollBar->setRange(0,1000);
    ui->customPlot->xAxis->setLabel("time(s)");
    ui->customPlot->axisRect()->setupFullAxesBox(true); //为每边画上刻度线,如果已经存在则将不执行
    ui->customPlot->xAxis->setRange(0,1000,Qt::AlignLeft); //这句设置 x 轴显示范围
    ui->customPlot->yAxis->setRange(0,40,Qt::AlignCenter);
    ui->customPlot->setMultiSelectModifier(Qt::ControlModifier);// 使用ctrl键来多选
    ui->customPlot->setContextMenuPolicy(Qt::CustomContextMenu);//自定义菜单
    ui->customPlot->legend->setSelectableParts(QCPLegend::spItems);// 图例本身不能被选择,只有里面的项可以被选择
    ui->customPlot->legend->setSelectedIconBorderPen(Qt::NoPen);// 设置图例里的项被选择时不显示Icon的边框
}

2、绘图

//绘图函数,一次只能绘一条,通过多次调用,改变linenumber,可实现不同曲线不同颜色
//linename为曲线名称,x、y分别为x轴和y轴数据,linenumber为当前为第几条曲线
void MainWindow::draw(QString lineName,QVector<double> x,QVector<double> y,int lineNumber)
{
    QPen pen;
    ui->customPlot->addGraph();//每条曲线都会独占一个graph()
    pen.setColor(QColor(qSin(lineNumber*1+1.2)*80+80, qSin(lineNumber*0.3+0)*80+80, qSin(lineNumber*0.3+1.5)*80+80));//改变颜色
    ui->customPlot->graph()->setPen(pen);       // 设置画笔
    ui->customPlot->graph()->setName(lineName);//图例名称
    ui->customPlot->graph()->setLineStyle(QCPGraph::LineStyle::lsLine);  // 折线
    ui->customPlot->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));//设置散点形状
    ui->customPlot->legend->setVisible(true); // 显示图例
    ui->customPlot->graph()->setData(x, y);//x和y
    ui->customPlot->graph()->rescaleAxes(true);//自动调整XY轴的范围
    // 支持鼠标拖拽轴的范围、滚动缩放轴的范围,左键点选图层(每条曲线独占一个图层),左键选中图例,选中图层,可多选
    ui->customPlot->setInteractions(QCP::iRangeDrag |QCP::iRangeZoom | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect);
    ui->customPlot->replot();//重绘曲线,每一次改变customplot窗口都要重绘一次,刷新界面
}

3、选中图例或图线实现隐藏、显示

(1)选中图例和曲线

在构造函数中先连接槽

	// 连接QCustomPlot的信号,selectionChangedByUser表明是由鼠标点击进行的选择
    // 这里主要就是同步图表和图例的显示
    connect(ui->customPlot, &QCustomPlot::selectionChangedByUser, this,&MainWindow::selectedShow);

再编写槽函数

// 选中图例中的项,或者选中曲线时
void MainWindow::selectedShow()
{
    for (int i=0; i < ui->customPlot->graphCount(); ++i) {
        QCPGraph *graph = ui->customPlot->graph(i);
        QCPPlottableLegendItem *item = ui->customPlot->legend->itemWithPlottable(graph);//图例中的每一个项

        //选中图例中的项,或者选中曲线时,两者都被选中
        if (item->selected() || graph->selected())
        {
            graph->setSelected(true);// 当图例项被选择时,选择图表全部的数据
            item->setSelected(true);
        }
    }
}
(2)显示隐藏菜单功能实现
和上述一样分步实现
connect(ui->customPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));
// 设置显示/隐藏菜单
void MainWindow::contextMenuRequest(QPoint pos)
{
    QMenu *menu = new QMenu(this);
    menu->setAttribute(Qt::WA_DeleteOnClose);

    double legendCounts = ui->customPlot->legend->selectTest(pos, false);
    double graphCounts = ui->customPlot->graph()->selectTest(pos,false);

    //图例菜单
    if (( legendCounts >= 0) || ( graphCounts >= 0))
    {
        menu->addAction("显示", this, SLOT(showGraph()));
        menu->addAction("隐藏", this, SLOT(hideGraph()));
    }

    menu->popup(ui->customPlot->mapToGlobal(pos));
}
// 被选中的曲线显示
void MainWindow::showGraph()
{
    for (int i=0; i<ui->customPlot->graphCount(); ++i)
    {
        QCPGraph *graphItem = ui->customPlot->graph(i);

        if (graphItem->selected())
        {
            graphItem->setVisible(true);
        }
    }
    ui->customPlot->replot();
}

// 被选中的曲线隐藏
void MainWindow::hideGraph()
{
    for (int i=0; i< ui->customPlot->graphCount(); ++i)
    {
        QCPGraph *graphItem = ui->customPlot->graph(i);

        if (graphItem->selected())
        {
            graphItem->setVisible(false);
        }
    }
    ui->customPlot->replot();
}

4、滑动条

connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this,SLOT(on_horizontalScrollBar_valueChanged(int)));
connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), this,SLOT(on_verticalScrollBar_valueChanged(int)));
void MainWindow::on_verticalScrollBar_valueChanged(int value)
{
    if (qAbs(ui->customPlot->yAxis->range().center()+value/100.0) > 0.01)
    {
        ui->customPlot->yAxis->setRange(-value/100.0, ui->customPlot->yAxis->range().size(),
        Qt::AlignCenter);
        ui->customPlot->replot();
    }
}

void MainWindow::on_horizontalScrollBar_valueChanged(int value)
{
    if (qAbs(ui->customPlot->xAxis->range().center()-value/100.0) > 0.01)
    {
        ui->customPlot->xAxis->setRange(value/100.0, ui->customPlot->xAxis->range().size(),
        Qt::AlignCenter);
        ui->customPlot->replot();
    }
}

小结

1、滑动条拖动部分数值调得不是很尽人意,所以滑动不是很顺畅

2、QVector的使用,初始定义时可以像数组一样规定长度和初始值

例:QVector<double> x(1000,0),y(1000,0);//绘图数据

后续往里面插数据有两种选择方式

  • y.append(value);//value为double类型

  • y[i]=value;

3、每一次改变customplot窗口都要重绘一次,刷新界面,不然会出现显示不及时的问题

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值