Qt高性能绘图控件之QCustomPlot(二):强大的图表性能
1 摘要
QCustomPlot 是一个用于在 Qt 应用程序中绘制高性能图形的控件。它提供了丰富的功能,可用于绘制各种类型的图形,如折线图、柱状图、饼图、散点图等。 QCustomPlot 的一些主要特点和优势:
- 高性能:QCustomPlot 针对绘图性能进行了优化,能够快速绘制大量数据点。
- 丰富的绘图功能:支持多种绘图类型,并且可以自定义绘图样式、颜色、标记等。
- 交互性:允许用户与图形进行交互,如缩放、平移、选择数据点等。
- 数据处理:可以方便地处理和显示数据,支持数据的动态更新。
- 可定制性:提供了丰富的接口和属性,允许用户根据自己的需求进行定制。
- 跨平台:适用于多种操作系统和平台,如 Windows、Linux、Mac OS 等。
- 与 Qt 集成:QCustomPlot 是 Qt 的一部分,可以与其他 Qt 控件和功能无缝集成。
使用 QCustomPlot 可以在 Qt 应用程序中创建专业的绘图界面,适用于科学计算、数据可视化、监控系统等领域。
2 绘图应用
2.1 波形曲线测量
在实时采集数据项目中或者动态数据展示分析中,通常会查看曲线数据点间隔值,Qt中使用QCustomPlot 来实现曲线数据测量。
核心代码
try {
//默认曲线选择
QCPGraph *graph = ui->widget_2->graph(0);
//设置游标初始位置(可以不设置)
QCPRange keyRange = customPlot->axisRect()->axis(QCPAxis::atBottom)->range();
float xValue1 = keyRange.upper * 0.2;
float xValue2 = keyRange.upper * 0.7;
QCPRange keyRange2 = customPlot->axisRect()->axis(QCPAxis::atLeft)->range();
float yValue = keyRange2.lower;
auto iter1 = graph->data()->findBegin(xValue1);
xValue1 = iter1->mainKey();
auto iter2 = graph->data()->findBegin(xValue2);
xValue2 = iter2->mainKey();
//左游标
QPen pen(graph->pen().color(),1.5,Qt::SolidLine); //颜色 、宽度、样式(直线)
m_lineLV = new QCPItemStraightLine(customPlot);
m_lineLV->setLayer("overlay");
m_lineLV->setPen(pen);//设置游标线的样式
m_lineLV->setClipToAxisRect(true);//自适应范围
m_lineLV->point1->setCoords(xValue1, 1);//起点坐标
m_lineLV->point2->setCoords(xValue1, 1);//终点坐标
m_lineLV->setVisible(true);
//右游标
m_lineRV = new QCPItemStraightLine(customPlot);
m_lineRV->setLayer("overlay");
m_lineRV->setPen(pen);
m_lineRV->setClipToAxisRect(true);
m_lineRV->point1->setCoords(xValue2, 1);
m_lineRV->point2->setCoords(xValue2, 1);
m_lineRV->setVisible(true);
//水平游标
m_lineH = new QCPItemStraightLine(customPlot);
m_lineH->setLayer("overlay");
m_lineH->setPen(pen);
m_lineH->setClipToAxisRect(true);
m_lineH->point1->setCoords(0, yValue);
m_lineH->point2->setCoords(keyRange.upper, yValue);
m_lineH->setVisible(true);
//编辑框显示初始位置
ui->lineEdit->setText(QString::number(m_lineLV->point1->key()));
ui->lineEdit_2->setText(QString::number(m_lineRV->point1->key()));
ui->lineEdit_3->setText(QString::number(m_lineH->point1->value()));
ui->widget_2->replot();
} catch (...) {
//FERROR("游标初始化异常!");
}
//建立槽函数
connect(ui->widget_2, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress(QMouseEvent*)));
connect(ui->widget_2, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMove(QMouseEvent*)));
connect(ui->widget_2, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseRelease(QMouseEvent*)));
鼠标点击事件 点击曲线图表游标显示
void MainWindow::mousePress(QMouseEvent* e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(e->button() == Qt::LeftButton)
{
bTracer1 = true;
tracer1->setVisible(true);
bTracer2 = true;
tracer2->setVisible(true);
}
if(e->button() == Qt::RightButton)
{
bTracer1 = false;
tracer1->setVisible(false);
bTracer2 = false;
tracer2->setVisible(false);
clickNum = 0;
}
curCustomPlot->replot();
}
}
鼠标双击事件 双击曲线图表游标显示
void MainWindow::mouseDoubleClick(QMouseEvent* e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(clickNum%2 == 0)
{
bTracer1 = false;
tracer1->setVisible(true);
}
else
{
bTracer2 = false;
tracer2->setVisible(true);
bTracer1 = false; //双击时会先触发单击事件,单击时会把bTracer1置为true,所以这里重新设置为false
}
clickNum++;
}
}
鼠标移动事件
void MainWindow::mouseMove(QMouseEvent *e)
{
QCustomPlot *curCustomPlot = qobject_cast<QCustomPlot *>(sender());
if(curCustomPlot == customPlot)
{
if(bTracer1)
{
int x = curCustomPlot->xAxis->pixelToCoord(e->pos().x());
int pos = x;
x1=x;
if(pos < 0)
{
return ;
}
//qDebug() << "POS:" << pos;
tracer1->position->setCoords