文章目录
- 成果展示
- 准备工作
- 主要代码
- 1、初始化
- 2、绘图
- 3、选中图例或图线实现隐藏、显示
- 4、滑动条
- 小结
成果展示
本文绘图用到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窗口都要重绘一次,刷新界面,不然会出现显示不及时的问题