QCustomPlot之Interaction简单解析

来源:互联网 发布:python readlines 编辑:程序博客网 时间:2024/06/11 06:48
Interaction实例中主要简单的使用了跟用户交互有关的一些plottables的信号和常用函数的调用。
主要用到的部件有QCPPlotTitle,QCPAxis,QCPLegend,QCPPlottableLegendItem,QCPGraph。
主要用到的函数
selectedParts()选中的部分
testFlag()测试选中的是否是某一部分
setSelectedParts()设置选中的部分
setRangeDrag()设置可以进行范围拖动的方向
setRangeZoom()设置可以缩放的方向
selectedGraphs()选中的graphs

clearGraphs()清除所有的graphs

//mainwindow.cpp文件简单解析

#include "mainwindow.h"#include "ui_mainwindow.h"//用户交互实例MainWindow::MainWindow(QWidget *parent) :  QMainWindow(parent),  ui(new Ui::MainWindow){  srand(QDateTime::currentDateTime().toTime_t());//设置随机种子  ui->setupUi(this);    //设置用户可以对customPlot进行那些操作  ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectAxes |                                  QCP::iSelectLegend | QCP::iSelectPlottables);  //设置x,y轴的坐标范围  ui->customPlot->xAxis->setRange(-8, 8);  ui->customPlot->yAxis->setRange(-5, 5);  //设置四个坐标轴都可见  ui->customPlot->axisRect()->setupFullAxesBox();  //在customPlot中插入一行并且添加一个标题元素  ui->customPlot->plotLayout()->insertRow(0);  ui->customPlot->plotLayout()->addElement(0, 0, new QCPPlotTitle(ui->customPlot, "Interaction Example"));  //设置x,y轴的标签并且设置图例可见  ui->customPlot->xAxis->setLabel("x Axis");  ui->customPlot->yAxis->setLabel("y Axis");  ui->customPlot->legend->setVisible(true);  //对图例进行一些字体大小,以及图例框中只有Item能选中的设置  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();  //绑定一些信号跟槽  // connect slot that ties some axis selections together (especially opposite axes):  connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));  // connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:  connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));  connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));    // make bottom and left axes transfer their ranges to top and right axes:  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 some interaction slots:  connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*,QCPPlotTitle*)), this, SLOT(titleDoubleClick(QMouseEvent*,QCPPlotTitle*)));  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 slot that shows a message in the status bar when a graph is clicked:  connect(ui->customPlot, SIGNAL(plottableClick(QCPAbstractPlottable*,QMouseEvent*)), this, SLOT(graphClicked(QCPAbstractPlottable*)));    // setup policy and connect slot for context menu popup:设置弹出式菜单  ui->customPlot->setContextMenuPolicy(Qt::CustomContextMenu);  connect(ui->customPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));}MainWindow::~MainWindow(){  delete ui;}/*函数功能描述: 双击标题响应函数,修改Plot标题函数参数:QMouseEvent*鼠标事件指针,QCPPlotTitle*被双击标题对象指针 */void MainWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title){  Q_UNUSED(event)  // 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();  }}/*函数功能描述: 坐标轴标签双击响应函数,修改坐标轴标签函数参数:axis坐标轴指针,part双击选中的部分 */void MainWindow::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part){  // Set an axis label by double clicking on it  if (part == QCPAxis::spAxisLabel) // only react when the actual axis label is clicked, not tick label or axis backbone  {    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();    }  }}/*函数功能描述: 图例双击槽函数,修改图例名称函数参数:legend选中的图例指针,item选中项的指针 */void MainWindow::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item){  // Rename a graph by double clicking on its legend item  Q_UNUSED(legend)  if (item) // only react if item was clicked (user could have clicked on border padding of legend where there is no item, then item is 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)    {      //设置图例项的名字并且重新绘制      plItem->plottable()->setName(newName);      ui->customPlot->replot();    }  }}/*函数功能描述: 选择改变槽函数,设置联动 */void MainWindow::selectionChanged(){  /*   normally, axis base line, axis tick labels and axis labels are selectable separately, but we want   the user only to be able to select the axis as a whole, so we tie the selected states of the tick labels   and the axis base line together. However, the axis label shall be selectable individually.      The selection state of the left and right axes shall be synchronized as well as the state of the   bottom and top axes.      Further, we want to synchronize the selection of the graphs with the selection state of the respective   legend item belonging to that graph. So the user can select a graph by either clicking on the graph itself   or on its legend item.  */  //设置坐标轴和刻度标签有一个被选中时同时被选中  // make top and bottom axes be selected synchronously, and handle axis and tick labels as one selectable object:  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);  }  // make left and right axes be selected synchronously, and handle axis and tick labels as one selectable object:  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);  }  //同步graph和图例中相应项  // synchronize selection of graphs with selection of corresponding legend items:  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->setSelected(true);    }  }}/*函数功能描述: 鼠标按下事件,只能在选中的坐标轴方向上进行拖拽 */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    if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))    ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->xAxis->orientation());  else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))    ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->yAxis->orientation());  else    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,y轴被选中只改变对应坐标轴的范围  if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))    ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->xAxis->orientation());  else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))    ui->customPlot->axisRect()->setRangeZoom(ui->customPlot->yAxis->orientation());  else    ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);}/*函数功能描述: 添加随机的Graph */void MainWindow::addRandomGraph(){  int n = 50; // number of points in graph  double xScale = (rand()/(double)RAND_MAX + 0.5)*2;  double yScale = (rand()/(double)RAND_MAX + 0.5)*2;  double xOffset = (rand()/(double)RAND_MAX - 0.5)*4;  double yOffset = (rand()/(double)RAND_MAX - 0.5)*5;  double r1 = (rand()/(double)RAND_MAX - 0.5)*2;  double r2 = (rand()/(double)RAND_MAX - 0.5)*2;  double r3 = (rand()/(double)RAND_MAX - 0.5)*2;  double r4 = (rand()/(double)RAND_MAX - 0.5)*2;  QVector<double> x(n), y(n);  for (int i=0; i<n; i++)  {    x[i] = (i/(double)n-0.5)*10.0*xScale + xOffset;    y[i] = (qSin(x[i]*r1*5)*qSin(qCos(x[i]*r2)*r4*3)+r3*qCos(qSin(x[i])*r4*2))*yScale + yOffset;  }    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)(rand()%5+1));  if (rand()%100 > 50)    ui->customPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(rand()%14+1)));  QPen graphPen;  graphPen.setColor(QColor(rand()%245+10, rand()%245+10, rand()%245+10));  graphPen.setWidthF(rand()/(double)RAND_MAX*2+1);  ui->customPlot->graph()->setPen(graphPen);  ui->customPlot->replot();}/*函数功能描述: 移除选中的graph */void MainWindow::removeSelectedGraph(){  if (ui->customPlot->selectedGraphs().size() > 0)  {    //如果选中的graph大于0则只移除第一个并且重绘    ui->customPlot->removeGraph(ui->customPlot->selectedGraphs().first());    ui->customPlot->replot();  }}/*函数功能描述: 移除所有的graphs并且重绘 */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) // context menu on legend requested  {    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  // general context menu on graphs requested  {    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())) // make sure this slot is really called by a context menu action, so it carries the data we need  {    bool ok;    int dataInt = contextAction->data().toInt(&ok);    if (ok)    {      ui->customPlot->axisRect()->insetLayout()->setInsetAlignment(0, (Qt::Alignment)dataInt);      ui->customPlot->replot();    }  }}/*函数功能描述: graph单击事件,将选中graph的名称显示到状态栏 */void MainWindow::graphClicked(QCPAbstractPlottable *plottable){    ui->statusBar->showMessage(QString("Clicked on graph '%1'.").arg(plottable->name()), 1000);}

0 0
原创粉丝点击