首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >QCustomPlot绘制交互图

QCustomPlot绘制交互图

原创
作者头像
Qt历险记
发布2025-07-12 13:25:25
发布2025-07-12 13:25:25
3360
举报
文章被收录于专栏:Qt6 研发工程师Qt6 研发工程师

点击上方"蓝字"关注我们

01、目录

>>>

QCustomPlot绘制正玄和余玄图

02、pro

>>>

代码语言:javascript
复制
#-------------------------------------------------
#
# Project created by QtCreator 2012-03-04T23:24:55
#
#-------------------------------------------------
# 添加QT模块
QT       += core gui
# 如果QT主版本号大于4,则添加widgets和printsupport模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport

# 如果QT主版本号大于4,则添加c++11配置
greaterThan(QT_MAJOR_VERSION, 4): CONFIG += c++11
# 如果QT主版本号小于5,则添加c++11编译选项
lessThan(QT_MAJOR_VERSION, 5): QMAKE_CXXFLAGS += -std=c++11

# 设置目标名称
TARGET = interaction-example
# 设置模板类型为应用程序
TEMPLATE = app

# 添加源文件
SOURCES += main.cpp\
        mainwindow.cpp \
        qcustomplot.cpp

# 添加头文件
HEADERS  += mainwindow.h \
            qcustomplot.h

# 添加表单文件
FORMS    += mainwindow.ui


03、mainwindow.h

>>>

代码语言:javascript
复制
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QInputDialog>
#include "qcustomplot.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT
  
public:
  // 构造函数
  explicit MainWindow(QWidget *parent = 0);
  // 析构函数
  ~MainWindow();
  
private slots:
  // 双击标题栏
  void titleDoubleClick(QMouseEvent *event);
  // 双击坐标轴标签
  void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
  // 双击图例
  void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item);
  // 选择改变
  void selectionChanged();
  // 鼠标按下
  void mousePress();
  // 鼠标滚轮
  void mouseWheel();
  // 添加随机图形
  void addRandomGraph();
  // 移除选中图形
  void removeSelectedGraph();
  // 移除所有图形
  void removeAllGraphs();
  // 上下文菜单请求
  void contextMenuRequest(QPoint pos);
  // 移动图例
  void moveLegend();
  // 图形点击
  void graphClicked(QCPAbstractPlottable *plottable, int dataIndex);
  
private:
  Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

04、mainwindow.cpp

>>>

代码语言:javascript
复制
#include "mainwindow.h"
#include "ui_mainwindow.h"

// MainWindow类的构造函数,初始化窗口和UI
MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  // 设置随机数种子 获取当前时间,并将其转换为自1970年1月1日以来的毫秒数,将毫秒数除以1000,得到秒数
  std::srand(QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0);
  // 设置UI
  ui->setupUi(this);
  
  // 设置交互方式
  // 设置自定义绘图控件的交互方式,包括范围拖动、范围缩放、选择坐标轴、选择图例和选择绘图元素
  ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |
                                  QCP::iSelectLegend | QCP::iSelectPlottables);

  // 设置坐标轴范围
  ui->customPlot->xAxis->setRange(-8, 8);
  ui->customPlot->yAxis->setRange(-5, 5);
  // 设置坐标轴 axisRect获取绘图区域 setupFullAxesBox自动为绘图区域添加顶部、底部、左侧和右侧的轴??
  ui->customPlot->axisRect()->setupFullAxesBox();
  
  // 设置标题
  ui->customPlot->plotLayout()->insertRow(0);
  QCPTextElement *title = new QCPTextElement(ui->customPlot, "Interaction Example", QFont("sans", 17, QFont::Bold));
  ui->customPlot->plotLayout()->addElement(0, 0, title);
  
  // 设置坐标轴标签
  ui->customPlot->xAxis->setLabel("x Axis");
  ui->customPlot->yAxis->setLabel("y Axis");
  // 设置图例
  ui->customPlot->legend->setVisible(true);
  QFont legendFont = font();
  legendFont.setPointSize(10);
  ui->customPlot->legend->setFont(legendFont);
  ui->customPlot->legend->setSelectedFont(legendFont);
  // 设置图例的可选择部分为图例项
  ui->customPlot->legend->setSelectableParts(QCPLegend::spItems); // legend box shall not be selectable, only legend items  

  // 添加随机图形
  addRandomGraph();
  addRandomGraph();
  addRandomGraph();
  addRandomGraph();

  // 重绘图形
  // 调整坐标轴范围,使其适应数据
  ui->customPlot->rescaleAxes();  

  // 连接槽函数,将一些轴的选择绑定在一起(特别是相反的轴):
  connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));
  // 连接槽函数,处理当轴被选择时,只有该方向可以被拖动和缩放:
  connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));
  connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
  
  // 使底部和左侧轴的范围同步到顶部和右侧轴:
  connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));
  connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));
  
  // 连接一些交互槽函数:
  connect(ui->customPlot, SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*)), this, SLOT(axisLabelDoubleClick(QCPAxis*,QCPAxis::SelectablePart)));
  connect(ui->customPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this, SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));
  connect(title, SIGNAL(doubleClicked(QMouseEvent*)), this, SLOT(titleDoubleClick(QMouseEvent*)));
  
  // 连接槽函数,当图形被点击时,在状态栏显示消息:
  connect(ui->customPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,int,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*,int)));
  
  // 设置策略并连接上下文菜单弹出槽函数:
  ui->customPlot->setContextMenuPolicy(Qt::CustomContextMenu);
  connect(ui->customPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));
}

// MainWindow类的析构函数,删除UI
MainWindow::~MainWindow()
{
  delete ui;
}

// 标题双击槽函数,双击标题时设置新的标题
void MainWindow::titleDoubleClick(QMouseEvent* event)
{
  Q_UNUSED(event) // 忽略event参数
  if (QCPTextElement *title = qobject_cast<QCPTextElement*>(sender())) // 如果sender()是一个QCPTextElement对象
  {
    // Set the plot title by double clicking on it
    bool ok;
    QString newTitle = QInputDialog::getText(this, "QCustomPlot example", "New plot title:", QLineEdit::Normal, title->text(), &ok); // 弹出一个对话框,让用户输入新的标题
    if (ok)
    {
      title->setText(newTitle); // 设置新的标题
      ui->customPlot->replot(); // 重新绘制图表
    }
  }
}

// 坐标轴标签双击槽函数,双击坐标轴标签时设置新的标签
void MainWindow::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part)
{
  // 设置轴标签通过双击轴标签
  if (part == QCPAxis::spAxisLabel) // 仅当实际轴标签被点击时做出反应,而不是刻度标签或轴主干
  {
    bool ok;
    // 弹出一个对话框,让用户输入新的轴标签
    QString newLabel = QInputDialog::getText(this, "QCustomPlot example", "New axis label:", QLineEdit::Normal, axis->label(), &ok);
    if (ok)
    {
      // 设置新的轴标签
      axis->setLabel(newLabel);
      // 重新绘制图表
      ui->customPlot->replot();
    }
  }
}

// 图例双击槽函数,双击图例项时重命名图形
void MainWindow::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item)
{
  // Rename a graph by double clicking on its legend item
  Q_UNUSED(legend)
  if (item) // 仅在点击了项目时做出反应(用户可能点击了图例边框的填充区域,此时item为0)
  {
    QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
    bool ok;
    // 弹出一个对话框,让用户输入新的图名
    QString newName = QInputDialog::getText(this, "QCustomPlot example", "New graph name:", QLineEdit::Normal, plItem->plottable()->name(), &ok);
    if (ok)
    {
      // 将新的图名赋值给plottable
      plItem->plottable()->setName(newName);
      // 重新绘制图表
      ui->customPlot->replot();
    }
  }
}

// 选择改变槽函数,同步轴的选择状态
void MainWindow::selectionChanged()
{
  /*
   通常情况下,轴基线、轴刻度标签和轴标签是可以分别选择的,但我们希望用户只能整体选择轴,
   因此我们将刻度标签和轴基线的选择状态绑定在一起。然而,轴标签可以单独选择。
   
   左轴和右轴的选择状态需要同步,底轴和顶轴的选择状态也需要同步。
   
   此外,我们希望将图形的选择状态与相应的图例项的选择状态同步。这样,用户可以通过点击图形本身或其图例项来选择图形。
  */
  // 使顶部和底部轴同步选择,并将轴和刻度标签作为一个可选择的对象:
  if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
      ui->customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
  {
    // 如果顶部或底部轴被选中,则将顶部和底部轴都设置为选中状态
    ui->customPlot->xAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
    ui->customPlot->xAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
  }
  // 使左侧和右侧轴同步选择,并将轴和刻度标签作为一个可选择的对象:
  if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
      ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
  {
    // 如果左侧或右侧轴被选中,则将左侧和右侧轴都设置为选中状态
    ui->customPlot->yAxis2->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
    ui->customPlot->yAxis->setSelectedParts(QCPAxis::spAxis|QCPAxis::spTickLabels);
  }
  
  // 同步图形的选择状态与相应的图例项的选择状态:
  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())
    {
      item->setSelected(true);
      graph->setSelection(QCPDataSelection(graph->data()->dataRange()));
    }
  }
}

// 鼠标按下槽函数,如果选择了轴,则只允许拖动该轴的方向
void MainWindow::mousePress()
{
  // if an axis is selected, only allow the direction of that axis to be dragged
  // if no axis is selected, both directions may be dragged
  
  // 如果x轴被选中
  if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))
    // 设置x轴可拖动
    ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->xAxis->orientation());
  // 如果y轴被选中
  else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))
    // 设置y轴可拖动
    ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->yAxis->orientation());
  // 否则
  else
    // 设置x轴和y轴都可拖动
    ui->customPlot->axisRect()->setRangeDrag(Qt::Horizontal|Qt::Vertical);
}

// 鼠标滚轮槽函数,如果选择了轴,则只允许缩放该轴的方向
void MainWindow::mouseWheel()
{
  // if an axis is selected, only allow the direction of that axis to be zoomed
  // if no axis is selected, both directions may be zoomed
  
  // 如果x轴被选中
  if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))
    // 设置x轴的缩放范围
    ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->xAxis->orientation());
  // 如果y轴被选中
  else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))
    // 设置y轴的缩放范围
    ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->yAxis->orientation());
  // 否则
  else
    // 设置水平和垂直方向的缩放范围
    ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);
}

// 添加随机图形槽函数,添加随机图形
void MainWindow::addRandomGraph()
{
  int n = 50; // number of points in graph
  // RAND_MAX 0x7fff
  // std::rand()用于生成一个介于0到RAND_MAX之间的随机整数。
  // (std::rand()/(double)RAND_MAX)将生成的随机整数转换为0到1之间的随机浮点数。
  // 对于xScale和yScale,通过加上0.5并乘以2,转换得到的随机浮点数的范围变为1到2之间,作为x轴和y轴的缩放因子。
  double xScale = (std::rand()/(double)RAND_MAX + 0.5)*2; // x轴缩放因子
  double yScale = (std::rand()/(double)RAND_MAX + 0.5)*2; // y轴缩放因子
  // 通过减去0.5并乘以4或10,转换得到的随机浮点数的范围变为-2到2或-5到5之间,作为x轴和y轴的偏移量。
  double xOffset = (std::rand()/(double)RAND_MAX - 0.5)*4; // x轴偏移量
  double yOffset = (std::rand()/(double)RAND_MAX - 0.5)*10; // y轴偏移量
  double r1 = (std::rand()/(double)RAND_MAX - 0.5)*2; // 参数r1
  double r2 = (std::rand()/(double)RAND_MAX - 0.5)*2; // 参数r2
  double r3 = (std::rand()/(double)RAND_MAX - 0.5)*2; // 参数r3
  double r4 = (std::rand()/(double)RAND_MAX - 0.5)*2; // 参数r4
  QVector<double> x(n), y(n);
  for (int i=0; i<n; i++)
  {
    /*
        (i/(double)n - 0.5) * 10.0 确保了 x 坐标的值在 -5 和 5 之间均匀分布。
        xScale 用于缩放这些值,使其范围在 [-5.0*xScale, 5.0*xScale) 之间。
        xOffset 用于对这些缩放后的值进行水平偏移,使其最终范围在 [-5.0*xScale + xOffset, 5.0*xScale + xOffset) 之间。
    */
    x[i] = (i/(double)n-0.5)*10.0*xScale + xOffset; // 计算x坐标
    /*
        (x[i]*r1*5):这部分计算是将x[i]乘以随机生成的r1因子,并乘以5。r1是一个范围在-1到1之间的随机数。
        qSin(x[i]*r1*5):对上述结果取正弦值,得到一个新的值。
        (x[i]*r2*3):将x[i]乘以随机生成的r2因子,并乘以3。r2是一个范围在-1到1之间的随机数。
        qCos(x[i]*r2):对上述结果取余弦值。
        (x[i]*r2*3)*r4*3:进一步将qCos(x[i]*r2)的结果乘以r2、3、r4和3。r4也是一个范围在-1到1之间的随机数。
        qSin(qCos(x[i]*r2)*r4*3):对上述结果取正弦值。
        qSin(x[i]*r1*5) * qSin(qCos(x[i]*r2)*r4*3):将上述两个正弦值相乘。
        qSin(x[i]*r1*5) * qSin(qCos(x[i]*r2)*r4*3) + r3*qCos(qSin(x[i])*r4*2):再加上r3*qCos(qSin(x[i])*r4*2),其中r3是一个范围在-1到1之间的随机数。
        * yScale:将上述结果乘以yScale,使得y值在不同的范围内。
        + yOffset:最后加上yOffset,其中yOffset是一个范围在-5到5之间的随机数。
    */
    y[i] = (qSin(x[i]*r1*5)*qSin(qCos(x[i]*r2)*r4*3)+r3*qCos(qSin(x[i])*r4*2))*yScale + yOffset; // 计算y坐标
  }
  
  ui->customPlot->addGraph(); // 添加新的图形
  ui->customPlot->graph()->setName(QString("New graph %1").arg(ui->customPlot->graphCount()-1)); // 设置图形名称
  ui->customPlot->graph()->setData(x, y); // 设置图形数据
  ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(std::rand()%5+1)); // 设置图形线型
  if (std::rand()%100 > 50)
      // std::rand()%14+1 生成一个范围在 1 到 14 之间的随机整数。这个整数用来选择 QCPScatterStyle::ScatterShape 枚举类型中的一个值。
    ui->customPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(std::rand()%14+1))); // 设置图形散点样式
  QPen graphPen;
  graphPen.setColor(QColor(std::rand()%245+10, std::rand()%245+10, std::rand()%245+10)); // 设置图形颜色
  graphPen.setWidthF(std::rand()/(double)RAND_MAX*2+1); // 设置图形线宽
  ui->customPlot->graph()->setPen(graphPen); // 设置图形画笔
  ui->customPlot->replot(); // 重绘图形
}

// 移除选中的图形
void MainWindow::removeSelectedGraph()
{
  // 如果有选中的图形
  if (ui->customPlot->selectedGraphs().size() > 0)
  {
    // 移除选中的图形
    ui->customPlot->removeGraph(ui->customPlot->selectedGraphs().first());
    // 重新绘制图形
    ui->customPlot->replot();
  }
}

// 移除所有图形
void MainWindow::removeAllGraphs()
{
  // 清除所有图形
  ui->customPlot->clearGraphs();
  // 重新绘制图形
  ui->customPlot->replot();
}

// 上下文菜单请求
void MainWindow::contextMenuRequest(QPoint pos)
{
  // 创建上下文菜单
  QMenu *menu = new QMenu(this);
  // 设置关闭时删除
  menu->setAttribute(Qt::WA_DeleteOnClose);
  
  // 如果在图例上请求上下文菜单
  if (ui->customPlot->legend->selectTest(pos, false) >= 0) 
  {
    // 添加移动图例的选项
    menu->addAction("Move to top left", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignLeft));
    menu->addAction("Move to top center", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignHCenter));
    menu->addAction("Move to top right", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop|Qt::AlignRight));
    menu->addAction("Move to bottom right", this, SLOT(moveLegend()))->setData((int)(Qt::AlignBottom|Qt::AlignRight));
    menu->addAction("Move to bottom left", this, SLOT(moveLegend()))->setData((int)(Qt::AlignBottom|Qt::AlignLeft));
  }
  else  // 在图形上请求上下文菜单
  {
    // 添加添加随机图形的选项
    menu->addAction("Add random graph", this, SLOT(addRandomGraph()));
    // 如果有选中的图形,添加移除选中的图形的选项
    if (ui->customPlot->selectedGraphs().size() > 0)
      menu->addAction("Remove selected graph", this, SLOT(removeSelectedGraph()));
    // 如果有图形,添加移除所有图形的选项
    if (ui->customPlot->graphCount() > 0)
      menu->addAction("Remove all graphs", this, SLOT(removeAllGraphs()));
  }
  
  // 在指定位置弹出上下文菜单
  menu->popup(ui->customPlot->mapToGlobal(pos));
}

// 移动图例
void MainWindow::moveLegend()
{
  // 确保这个槽函数是由上下文菜单动作调用的,并携带我们需要的数据
  if (QAction* contextAction = qobject_cast<QAction*>(sender())) 
  {
    bool ok;
    // 获取数据
    int dataInt = contextAction->data().toInt(&ok);
    if (ok)
    {
      // 设置图例位置
      ui->customPlot->axisRect()->insetLayout()->setInsetAlignment(0, (Qt::Alignment)dataInt);
      // 重新绘制图形
      ui->customPlot->replot();
    }
  }
}

// 图形点击事件
void MainWindow::graphClicked(QCPAbstractPlottable *plottable, int dataIndex)
{
  // 由于我们知道图中只有QCPGraphs,我们可以立即访问interface1D()
  // 通常最好先检查interface1D()是否返回非零,然后再使用它。
  double dataValue = plottable->interface1D()->dataMainValue(dataIndex);
  // 构造消息
  QString message = QString("Clicked on graph '%1' at data point #%2 with value %3.").arg(plottable->name()).arg(dataIndex).arg(dataValue);
  // 显示消息
  ui->statusBar->showMessage(message, 2500);
}



05、mainwindow.ui

>>>

06、演示

>>>

总结

>>>

QCPAbstractPlottable 是 QCustomPlot 库中的一个抽象基类,用于表示图表中的可绘制对象。QCustomPlot 是一个功能强大的 C++ 库,用于在 Qt 应用程序中创建交互式图表。

QCPAbstractPlottable 提供了一些基本的接口和功能,这些功能可以被具体的绘图对象(如曲线、散点图、条形图等)继承和扩展。以下是一些关键点:

  1. 绘制方法QCPAbstractPlottable 提供了 draw 方法,用于在图表上绘制对象。这个方法通常由 QCustomPlot 的内部机制调用。
  2. 数据管理QCPAbstractPlottable 负责管理绘图所需的数据。例如,曲线图需要管理一系列的点,而散点图需要管理一系列的坐标。
  3. 交互性QCPAbstractPlottable 提供了一些接口,用于处理用户交互,如鼠标点击、悬停等。
  4. 样式QCPAbstractPlottable 提供了一些接口,用于设置和获取绘图对象的样式,如颜色、线型、标记等。
  5. 事件处理QCPAbstractPlottable 可以处理一些事件,如鼠标事件、键盘事件等。

QCPGraph 是 QCustomPlot 库中的一个类,用于表示图表中的曲线图。它继承自 QCPAbstractPlottable,并提供了绘制和操作曲线所需的功能。

以下是一些 QCPGraph 的关键点:

  1. 数据管理QCPGraph 可以管理一系列的点,这些点定义了曲线的形状。数据可以通过 addData 方法添加,也可以通过 setData 方法一次性设置。
  2. 样式QCPGraph 提供了一些接口,用于设置和获取曲线的样式,如颜色、线型、标记等。
  3. 交互性QCPGraph 可以处理鼠标事件,如点击、悬停等,并可以显示数据点的信息。

QCPDataSelection 是 QCustomPlot 库中的一个类,用于表示图表中数据点的选择。它通常用于处理用户交互,如选择数据点、拖动选择区域等。

以下是一些 QCPDataSelection 的关键点:

  1. 数据点选择QCPDataSelection 可以表示一个或多个数据点的选择。每个数据点由其在数据集中的索引表示。
  2. 选择范围QCPDataSelection 可以表示一个选择范围,由起始和结束索引定义。
  3. 选择类型QCPDataSelection 可以表示不同的选择类型,如单个数据点、连续数据点、非连续数据点等。
  4. 操作QCPDataSelection 提供了一些方法,用于添加、删除、清除选择,以及检查是否包含特定的数据点。

❤❤❤

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 点击上方"蓝字"关注我们
  • 01、目录
  • 02、pro
  • 03、mainwindow.h
  • 04、mainwindow.cpp
  • 05、mainwindow.ui
  • 06、演示
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档