QCustomPlot之数据选择(十八)

效果图

数据选择粒度

可以通过函数QCPAbstractPlottable::setSelectable(所有的图表类都继承自QCPAbstractPlottable)设置数据选择的粒度,如下图所示:

数据选择粒度

数据选择方式及数据读取

一般来说,数据选择是通过鼠标来进行的,即鼠标点击或者鼠标框选,鼠标点击选择通过函数 QCustomPlot::setInteractions 设置相应的枚举量即可,如果需要多选,则需要 QCustomPlot::setMultiSelectModifier 设置多选时使用的按键以及 setInteractions 设置枚举量包含 QCP::iMultiSelect ;而鼠标框选则通过 QCustomPlot::setSelectionRectMode 设置框选时的枚举类型为 srmSelect ,QCustomPlot还给了一个 srmCustom 类型让我们自定义框选时的行为,只需要连接 QCPSelectionRect::accepted 信号即可

已被选择的数据可以通过QCPAbstractPlottable::selection函数读取,其返回QCPDataSelection类,QCPDataSelection表现为多个选择范围的集合QList< QCPDataRange >,而QCPDataRange是单个数据选择的范围,包含被选择数据的开始位置以及结束位置(通俗的说就是下标index),注意这里遵循左闭右开原则

多个选择部分的对象

在QCustomPlot中轴QCPAxis和图例QCPLegend等可以有多个部分可以被选择,由枚举SelectablePart决定可以被选择的部分,如图所示:
选择轴的某个部分

数据选择的风格

QCustomPlot引入了QCPSelectionDecorator来决定数据被选择时的风格,主要有画笔、画刷和散点图三种风格

全部源码
void MainWindow::setupLineStyleDemo(QCustomPlot *customPlot)
{
    customPlot->legend->setVisible(true);
    customPlot->legend->setFont(QFont("Helvetica", 9));
    QPen pen;
    QStringList lineNames;
    lineNames << "lsNone" << "lsLine" << "lsStepLeft" << "lsStepRight" << "lsStepCenter" << "lsImpulse";

    for (int i = QCPGraph::lsNone; i <= QCPGraph::lsImpulse; ++i)
    {
        customPlot->addGraph();
        pen.setColor(QColor(qSin(i*1+1.2)*80+80, qSin(i*0.3+0)*80+80, qSin(i*0.3+1.5)*80+80));
        customPlot->graph()->setPen(pen);       // 设置图表的画笔
        customPlot->graph()->setName(lineNames.at(i-QCPGraph::lsNone));
        customPlot->graph()->setLineStyle((QCPGraph::LineStyle)i);  // 设置图表线段的风格
        customPlot->graph()->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 5));  // 设置图表散点图的样式

        QVector<double> x(15), y(15);
        for (int j=0; j<15; ++j)
        {
            x[j] = j/15.0 * 5*3.14 + 0.01;
            y[j] = 7*qSin(x[j])/x[j] - (i-QCPGraph::lsNone)*5 + (QCPGraph::lsImpulse)*5 + 2;
        }
        customPlot->graph()->setData(x, y);
        customPlot->graph()->rescaleAxes(true);
    }
    // 放大一点
    customPlot->yAxis->scaleRange(1.1, customPlot->yAxis->range().center());
    customPlot->xAxis->scaleRange(1.1, customPlot->xAxis->range().center());

    customPlot->xAxis->setTicks(true);
    customPlot->yAxis->setTicks(true);
    customPlot->xAxis->setTickLabels(true);
    customPlot->yAxis->setTickLabels(true);

    customPlot->axisRect()->setupFullAxesBox();
}

void MainWindow::setupSelectionDemo(QCustomPlot *customPlot)
{
    setupLineStyleDemo(customPlot);

    customPlot->setInteractions(QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect);   // 轴、图例、图表可以被选择,并且是多选的方式
    customPlot->setSelectionRectMode(QCP::srmSelect);             // 鼠标框选
    customPlot->setMultiSelectModifier(Qt::ControlModifier);     // 使用ctrl键来多选
    customPlot->xAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels);   // 轴的三个部分都可以被选择
    customPlot->yAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels);
    customPlot->xAxis->setLabel("xAxis");
    customPlot->yAxis->setLabel("yAxis");
    customPlot->legend->setSelectableParts(QCPLegend::spItems);       // 图例本身不能被选择,只有里面的项可以被选择
    customPlot->legend->setSelectedIconBorderPen(Qt::NoPen);           // 设置图例里的项被选择时不显示Icon的边框

    for (int i=0; i < customPlot->graphCount(); ++i) {
        QCPGraph *graph = customPlot->graph(i);
        graph->setSelectable(QCP::stDataRange);
    }

    // 连接QCustomPlot的信号,selectionChangedByUser表明是由鼠标点击进行的选择
    // 这里主要就是同步图表和图例的显示
    connect(customPlot, &QCustomPlot::selectionChangedByUser, [customPlot](){
        for (int i=0; i < customPlot->graphCount(); ++i) {
            QCPGraph *graph = customPlot->graph(i);
            QCPPlottableLegendItem *item = customPlot->legend->itemWithPlottable(graph);

            if (item->selected() && !graph->selected())
                graph->setSelection(QCPDataSelection(graph->data()->dataRange()));             // 当图例项被选择时,选择图表全部的数据
            else if (graph->selected())
                item->setSelected(true);
        }
    });
}
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值