Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
qt绘制轨迹线_qt绘制轨迹线,希望能够帮助你!!!。
最近有一个需求是能绘制多条曲线且能光标跟随,上网搜了很多相关的资料,如下边这个博客中查到了鼠标更随的相关代码,他的图如下所示——原文链接
还有一篇如下所示——原文链接
第一篇博主的实现方法其实已经比较完善了但是我按照他的方法去做后构造函数有点问题,所以对其做了一些修改之后得到如下结果——
#ifndef MYTRACER_H #define MYTRACER_H #include <QObject> #include "qcustomplot.h" enum TracerType {
XAxisTracer, YAxisTracer, DataTracer }; class myTracer : public QObject {
Q_OBJECT public: public: explicit myTracer(QCustomPlot *_plot,QCPGraph *_graph, TracerType _type);//这里与原贴不同,按照原贴构造总是过不去 ~myTracer(); void setPen(const QPen &pen); void setBrush(const QBrush &brush); void setText(const QString &text); void setLabelPen(const QPen &pen); void updatePosition(double xValue, double yValue); protected: void setVisible(bool visible); protected: QCustomPlot *plot ; //传入实例化的QcustomPlot QCPGraph *graph; //这里是存传入的绘图图层 QCPItemTracer *tracer; // 跟踪的点 QCPItemText *label; // 显示的数值 QCPItemLine *arrow; // 箭头 TracerType type; bool visible; signals: public slots: }; #endif // MYTRACER_H
#include "mytracer.h" myTracer::myTracer(QCustomPlot *_plot, QCPGraph *_graph, TracerType _type) : plot(_plot), graph(_graph), type(_type), visible(false) {
if (plot) {
tracer = new QCPItemTracer(plot); tracer->setStyle(QCPItemTracer::tsPlus);//可以选择设置追踪光标的样式,这个是小十字,还有大十字,圆点等样式 // tracer->setPen(QPen(Qt::red)); tracer->setPen(graph->pen());//设置tracer的颜色 tracer->setBrush(graph->pen().color()); tracer->setSize(10); label = new QCPItemText(plot); label->setLayer("overlay"); label->setClipToAxisRect(false); label->setPadding(QMargins(5, 5, 5, 5)); label->position->setParentAnchor(tracer->position); label->setFont(QFont("宋体", 10)); arrow = new QCPItemLine(plot); arrow->setLayer("overlay"); arrow->setPen(graph->pen());//设置箭头的颜色 arrow->setClipToAxisRect(false); arrow->setHead(QCPLineEnding::esSpikeArrow); switch (type) {
case XAxisTracer: {
tracer->position->setTypeX(QCPItemPosition::ptPlotCoords); tracer->position->setTypeY(QCPItemPosition::ptAxisRectRatio); label->setBrush(QBrush(QColor(244, 244, 244, 100))); label->setPen(QPen(Qt::black)); label->setPositionAlignment(Qt::AlignTop|Qt::AlignHCenter); arrow->end->setParentAnchor(tracer->position); arrow->start->setParentAnchor(arrow->end); arrow->start->setCoords(20, 0);//偏移量 break; } case YAxisTracer: {
tracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio); tracer->position->setTypeY(QCPItemPosition::ptPlotCoords); label->setBrush(QBrush(QColor(244, 244, 244, 100))); label->setPen(QPen(Qt::black)); label->setPositionAlignment(Qt::AlignRight|Qt::AlignHCenter); arrow->end->setParentAnchor(tracer->position); arrow->start->setParentAnchor(label->position); arrow->start->setCoords(-20, 0);//偏移量 break; } case DataTracer: {
tracer->position->setTypeX(QCPItemPosition::ptPlotCoords); tracer->position->setTypeY(QCPItemPosition::ptPlotCoords); label->setBrush(QBrush(QColor(244, 244, 244, 150))); label->setPen(graph->pen()); label->setPositionAlignment(Qt::AlignLeft|Qt::AlignVCenter); arrow->end->setParentAnchor(tracer->position); arrow->start->setParentAnchor(arrow->end); arrow->start->setCoords(25, 0); break; } default: break; } setVisible(false); } } myTracer::~myTracer() {
if (tracer) plot->removeItem(tracer); if (label) plot->removeItem(label); } void myTracer::setPen(const QPen &pen) {
tracer->setPen(pen); arrow->setPen(pen); } void myTracer::setBrush(const QBrush &brush) {
tracer->setBrush(brush); } void myTracer::setLabelPen(const QPen &pen) {
label->setPen(pen); } void myTracer::setText(const QString &text) {
label->setText(text); } void myTracer::setVisible(bool visible) {
tracer->setVisible(visible); label->setVisible(visible); arrow->setVisible(visible); } void myTracer::updatePosition(double xValue, double yValue) {
if (!visible) {
setVisible(true); visible = true; } if (yValue > plot->yAxis->range().upper) yValue = plot->yAxis->range().upper; switch (type) {
case XAxisTracer: {
tracer->position->setCoords(xValue, 1); label->position->setCoords(0, 15); arrow->start->setCoords(0, 15); arrow->end->setCoords(0, 0); break; } case YAxisTracer: {
tracer->position->setCoords(1, yValue); label->position->setCoords(-20, 0); break; } case DataTracer: {
tracer->position->setCoords(xValue, yValue); label->position->setCoords(25, 0); break; } default: break; } }
附上我的实现主函数
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QFile> #include <QTextStream> #include <string> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this); m_Plot = QSharedPointer<QCustomPlot> (new QCustomPlot()); ui->verticalLayout->addWidget(m_Plot.data()); //设置基本坐标轴(左侧Y轴和下方X轴)可拖动、可缩放、曲线可选、legend可选、设置伸缩比例,使所有图例可见 m_Plot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |QCP::iSelectLegend | QCP::iSelectPlottables); m_Plot->legend->setVisible(true); m_Plot->legend->setFont(QFont("Helvetica",9)); m_Plot->legend->setBrush(QColor(255,255,255,100)); // generate some data: QVector<double> x(), y(), y1(), y2(); for (int i=0; i<; ++i) {
x[i] = i; y[i] = x[i]/50000 * x[i]/50000; y1[i] = y[i] * 1.2; y2[i] = y[i] * 1.4; } QVector<QVector<double> > vec; vec.push_back(x); vec.push_back(y); m_value.push_back(vec); QVector<QVector<double> >().swap(vec); vec.push_back(x); vec.push_back(y1); m_value.push_back(vec); QVector<QVector<double> >().swap(vec); vec.push_back(x); vec.push_back(y2); m_value.push_back(vec); QVector<QVector<double> >().swap(vec); StaticDataPlot(m_value); m_Plot->xAxis->rescale(true); m_Plot->axisRect()->axis(QCPAxis::atBottom, 0)->setPadding(10); // add some padding to have space for tags m_TraserX = QSharedPointer<myTracer> (new myTracer(m_Plot.data(), m_Plot->graph(0), XAxisTracer)); connect(m_Plot.data(), SIGNAL(mouseMove(QMouseEvent*)), this,SLOT(showTracer(QMouseEvent*))); m_Plot->replot(); } MainWindow::~MainWindow() {
delete ui; } void MainWindow::showTracer(QMouseEvent *event) {
double x = m_Plot->xAxis->pixelToCoord(event->pos().x()); m_TraserX->updatePosition(x, 0); m_TraserX->setText(QString::number(x, 'f', 2)); for(int i=0;i<m_Graph.size();i++) {
double y = 0; QSharedPointer<QCPGraphDataContainer> tmpContainer; tmpContainer = m_Graph[i]->data(); //使用二分法快速查找所在点数据!!!敲黑板,下边这段是重点 int low = 0, high = tmpContainer->size(); while(high > low) {
int middle = (low + high) / 2; if(x < tmpContainer->constBegin()->mainKey() || x > (tmpContainer->constEnd()-1)->mainKey()) break; if(x == (tmpContainer->constBegin() + middle)->mainKey()) {
y = (tmpContainer->constBegin() + middle)->mainValue(); break; } if(x > (tmpContainer->constBegin() + middle)->mainKey()) {
low = middle; } else if(x < (tmpContainer->constBegin() + middle)->mainKey()) {
high = middle; } if(high - low <= 1) {
//差值计算所在位置数据 y = (tmpContainer->constBegin()+low)->mainValue() + ( (x - (tmpContainer->constBegin() + low)->mainKey()) * ((tmpContainer->constBegin()+high)->mainValue() - (tmpContainer->constBegin()+low)->mainValue()) ) / ((tmpContainer->constBegin()+high)->mainKey() - (tmpContainer->constBegin()+low)->mainKey()); break; } } m_Tracer[i]->updatePosition(x, y); m_Tracer[i]->setText(QString::number(y, 'f', 2)); } m_Plot->replot(); }
介于很多小伙伴找我咨询代码问题,找到之前面目全非的代码重新修改编译了一下,可能有一点小不同但是效果相同,小手点下关注再去下载哦~
CustomPlotTest.zip
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章