人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

Qt自定義Plot實現(xiàn)曲線繪制的詳細(xì)過程

發(fā)布日期:2021-12-15 07:17 | 文章來源:站長之家

簡介

實現(xiàn)了qt繪制曲線功能,包含arm觸摸屏多點觸控縮放(只支持兩點),實時曲線繪制,數(shù)據(jù)點根據(jù)繪制寬度優(yōu)化,跟蹤點數(shù)據(jù)獲取,雙坐標(biāo)等功能

演示

代碼

頭文件 plot.h

/*
 * 作者:老人與海
 * 博客:https://blog.csdn.net/qq_41340733
 * 代碼不保證穩(wěn)定性,請勿用于商業(yè)用途
 */
#ifndef PLOT_H
#define PLOT_H
#include <QWidget>
#include <QTimer>
#include <QList>
#include <QWheelEvent>
#include <QMouseEvent>
#include "plotdata.h"
typedef struct _RangeVal
{
 double Beg;
 double End;
 double offSet;
 bool IsOffSet;
 _RangeVal()
 {
  Beg=0;
  End=0;
  offSet=0;
  IsOffSet=false;
 }
}_RangeVal;
//鼠標(biāo)跟中點
class Tracking
{
public:
 Tracking()
 {
  m_IsDraw=false;
  m_IsMove=false;
  m_IsInit=false;
  m_First=false;
  m_radius=25;
  m_PointCenter=QPoint(0,0);
 }
 ~Tracking(){}
 bool getIsRange(QPoint point)
 {
  if(point.x()>(m_PointCenter.x()-m_radius)&&
 point.x()<(m_PointCenter.x()+m_radius)&&
 point.y()>(m_PointCenter.y()-m_radius)&&
 point.y()<(m_PointCenter.y()+m_radius))
  {
return true;
  }else{
return false;
  }
 }
public:
 bool m_IsDraw;
 bool m_IsMove;//鼠標(biāo)焦點
 bool m_IsInit;
 bool m_First;
 int m_radius;
 QPoint m_PointCenter;//繪制圓心
};
/**
 * @brief The CoorAxis class
 * 類名:CoorAxis
 * 功能:坐標(biāo)軸部件,用來繪制XY坐標(biāo)軸,使用時必須用Plot的ticker類進(jìn)行初始化,否則無法正常繪制坐標(biāo)
 */
class CoorAxis : public QWidget
{
 Q_OBJECT
public:
 explicit CoorAxis(QWidget *parent = nullptr,Ticker *ticker= nullptr);
 virtual ~CoorAxis();
 Ticker *ticker(){ return m_Ticker; }
 void mouseMove(QMouseEvent *event);
signals:
 void sig_UpdateUI();
public slots:
 void slots_sendCoorWheel(QWheelEvent *event);
 void slots_sendCoorMouse(QMouseEvent *event,QPoint point,bool IsFirst=false);
protected:
void paintEvent(QPaintEvent *event);
void drawTickerX(QPainter *painter);//繪制X軸
void drawTickerY_L(QPainter *painter);//繪制左邊Y軸
void drawTickerY_R(QPainter *painter);//繪制右邊Y軸
void wheelEvent(QWheelEvent *event);//滾輪事件,縮放曲線圖像
void mousePressEvent(QMouseEvent *event);//按下事件,記錄坐標(biāo)和按下標(biāo)志
void mouseReleaseEvent(QMouseEvent *event);//抬起事件,取消按下標(biāo)志
void mouseMoveEvent(QMouseEvent *event);//鼠標(biāo)移動事件,移動曲線
protected:
Ticker *m_Ticker;
int m_LastLength;
int m_margin;
bool IsPress=false;
QPoint m_FirstPoint;
};

class Plot : public QWidget
{
 Q_OBJECT
public:
 explicit Plot(QWidget *parent=nullptr);
 virtual ~Plot();
 void ValueInit();
 Ticker *tickerX();
 Ticker *tickerL();
 Ticker *tickerR();
 void addGraph();
 void GraphClear(){ m_XyGraph.clear(); }
 int getGraphCount(){ return m_XyGraph.count(); }
 _XYList *Graph(int index);
 QList<_XYList> &GraphGroup(){ return m_XyGraph; }
 void setTrackVisibel(bool isVisbel){ m_Tracking.m_IsDraw=isVisbel; }
 bool getTrackVisibel(){ return m_Tracking.m_IsDraw; }
 void setIsDrawPath(bool value){ m_IsDrawPath=value; }
 bool getIsDrawPath(){ return m_IsDrawPath; }
 void coordToPixel(_COORDINATEVALUE *Value,_TICKERTYPE Type);
 void coordToPixel(double &key,double &value,_TICKERTYPE Type);
 void PixelToCoorKey(double &key,_TICKERTYPE Type);
 void PixelToCoorValue(double &value,_TICKERTYPE Type);
 void PixelToCoord(QPointF &pointf,_TICKERTYPE Type);
 void getOptimizedLineData(QVector<QPointF> *lineData,int index);
 void calculateTrackValue(QPoint Point);
 void setBackgroundColor(QColor color){ m_BackgroundColor=color; }
 QColor getBackgroundColor(){ return m_BackgroundColor; }
signals:
 void sig_sendCoorWheel(QWheelEvent *event);
 void sig_sendCoorMouse(QMouseEvent *event,QPoint point,bool IsFirst=false);
 void sig_UpdateUI();
 void sig_UpdateTrack();//刷新跟蹤點數(shù)據(jù)
public slots:
protected:
void paintEvent(QPaintEvent *event);
void drawGrid(QPainter *painter);//繪制網(wǎng)格
void drawPath(QPainter *painter);//繪制曲線
void drawCursor(QPainter *painter);//繪制跟蹤點
void drawTickerX(QPainter *painter);//繪制X軸
void drawTickerY_L(QPainter *painter);//繪制左邊Y軸
void drawTickerY_R(QPainter *painter);//繪制右邊Y軸
void wheelEvent(QWheelEvent *event);//滾輪事件,縮放曲線圖像
void mousePressEvent(QMouseEvent *event);//按下事件,記錄坐標(biāo)和按下標(biāo)志
void mouseReleaseEvent(QMouseEvent *event);//抬起事件,取消按下標(biāo)志
void mouseMoveEvent(QMouseEvent *event);//鼠標(biāo)移動事件,移動曲線
void showEvent(QShowEvent *event);//顯示事件
bool event(QEvent *event);//事件,實現(xiàn)多點觸控功能,目前只對兩個觸控點做了處理
public:
QPixmap m_PixMapCursor;//跟蹤點繪制圖像緩沖
Tracking m_Tracking;
protected:
Ticker *m_TickerX;
Ticker *m_TickerL;
Ticker *m_TickerR;
bool IsPress=false;
bool m_IsTouch=false;
QPoint m_ClickedPoint;
qreal m_scaleFactorX=0.0;
qreal m_scaleFactorY=0.0;
QList<_XYList> m_XyGraph;
QColor m_BackgroundColor;
bool m_IsDrawPath;//是否繪制曲線,在多線程添加數(shù)據(jù)的時候調(diào)用,添加數(shù)據(jù)時禁止繪制曲線
private:
friend class Ticker;
};
class CurveWid : public QWidget
{
 Q_OBJECT
public:
 explicit CurveWid(QWidget *parent = nullptr);
 void DataInit();
 void reUpdate();
 void reUpdateAll();
signals:
public slots:
 void slots_UpdateUI();
 void slots_TimeOut();
protected:
 void paintEvent(QPaintEvent *event);
public:
 CoorAxis *m_AxisX;
 CoorAxis *m_AxisL;
 CoorAxis *m_AxisR;
 Plot *m_Plot;
 QTimer *m_Timer;
};

#endif // PLOT_H

頭文件plotdata.h

/*
 * 作者:老人與海 
 * 博客:https://blog.csdn.net/qq_41340733
 * 代碼不保證穩(wěn)定性,請勿用于商業(yè)用途
 */

#ifndef PLOTDATA_H
#define PLOTDATA_H
#include <QObject>
#include <QVector>
#include <QColor>
class CoorAxis;
//_COORDINATEVALUE單個數(shù)據(jù)點結(jié)構(gòu)體
typedef struct _COORDINATEVALUE
{
 double Key;
 double Value;
 _COORDINATEVALUE()
 {
  Key=0;
  Value=0;
 }
}_COORDINATEVALUE;
//坐標(biāo)軸繪制的文本類型,包括時間毫秒,時間秒,數(shù)值
typedef enum _TEXT_TYPE
{
 _TimeMs,
 _TimeS,
 CountVal
}_TEXT_TYPE;
//坐標(biāo)軸類型,XAxis表示X軸,YAxis_L表示左邊的Y軸,YAxis_R表示右邊的Y軸
typedef enum _TICKERTYPE
{
 XAxis=0,
 YAxis_L=1,
 YAxis_R=2
}_TICKERTYPE;
//坐標(biāo)縮放前的坐標(biāo)值,_begVal坐標(biāo)起始值,_endVal坐標(biāo)結(jié)束值,_siteVal坐標(biāo)中點,
//多點觸控的時候先記錄坐標(biāo)的原始值,然后根據(jù)手勢距離對原始進(jìn)行縮放
typedef struct _Scale
{
 double _begVal=0.0;
 double _endVal=0.0;
 double _siteVal=0.0;
}_Scale;
/**
 * @brief The _XYList class
 * 功能:單條曲線的數(shù)據(jù)結(jié)構(gòu)類型,包括坐標(biāo)軸類型,曲線顏色,
 * 最多可繪制的曲線點數(shù),等功能等;
 */
class _XYList
{
public:
 explicit _XYList();
 virtual ~_XYList(){}
 int Count();//實際有效的數(shù)據(jù)點
 int CountAll();//所有的數(shù)據(jù)點,包括被移除的記錄
 int getRemoveCount(){ return  m_removeCount; }
 _COORDINATEVALUE &getPoint(int index);
 void addData(const double Key,const double Value);
 void removefirst();
 void cleanBuff();
 int size() const { return m_CoodValue.size()-m_removeCount; }
 QVector<_COORDINATEVALUE> *data();
 void setPointCountMax(int Count);
 int getPointMax(){ return m_MaxPointCount; }
 void setColor(QColor color){ m_Color=color; }
 QColor getColor(){ return m_Color; }
 void setAxisType(_TICKERTYPE type){ m_Type=type; }
 _TICKERTYPE &getAixsType(){ return m_Type; }
 int getBegindex(const double &TmpKey);
 int getEndindex(const double &TmpKey);
 int getCoorToIndex(const double &TmpKey);
 _COORDINATEVALUE getTrackValue(){ return TrackValue; }
 void setTrackValue(const _COORDINATEVALUE value){ TrackValue=value; }
 void setTrackValue(const double key,const double value){
  TrackValue.Key=key;
  TrackValue.Value=value;
 }
 bool TracckIsValid(){ return IsValid; }
 void setTrackIsvalid(bool val){ IsValid=val; }
 void setVisible(bool val){ m_Visible=val; }
 bool getVisible(){ return m_Visible; }
 _COORDINATEVALUE getMaxValue(){ return m_MaxValue; }
 _COORDINATEVALUE getMinValue(){ return m_MinValue; }
 QVector<_COORDINATEVALUE>::const_iterator constBegIte(){ return (m_CoodValue.begin()+m_removeCount); }
 QVector<_COORDINATEVALUE>::const_iterator constEndIte(){ return m_CoodValue.end(); }
protected:
 QVector<_COORDINATEVALUE> m_CoodValue;
 int m_MaxPointCount;//實際數(shù)據(jù)點,根據(jù)總數(shù)據(jù)點是否達(dá)到這和數(shù)目而對m_removeCount進(jìn)行操作
 int m_removeCount;//被移除的次數(shù),會先記錄,到達(dá)一定數(shù)據(jù)時候會重新分分配m_CoodValue大小,提高了添加固定點數(shù)據(jù)時候的速度
 _TICKERTYPE m_Type;
 QColor m_Color;
 _COORDINATEVALUE TrackValue;//蹤點的值
 bool IsValid;//判斷跟蹤點的值是否有效
 bool m_Visible;//是否繪制,既可見度
 _COORDINATEVALUE m_MaxValue;
 _COORDINATEVALUE m_MinValue;
};
/**
 * @brief The Ticker class
 * 坐標(biāo)軸數(shù)據(jù)結(jié)構(gòu)類,這里描述了坐標(biāo)的主刻度,子刻度,刻度長度,
 * 坐標(biāo)范圍,坐標(biāo)軸的類型(X還是Y 參考_TICKERTYPE)等信息
 */
class Ticker
{
public:
 explicit Ticker()
 {
 MainLineCount=15;
 SubLineCount=6;
 Mainlength=10;
 Sublength=10;
 Type=_TICKERTYPE::XAxis;
 m_RangeBeg=0;
 m_RangeEnd=500;
 }
 virtual ~Ticker(){}
 void setMainLineCount(const int count){ MainLineCount=count; }
 void setSubLineCount(const int count){ SubLineCount=count; }
 void setMainLineLength(const int length){ Mainlength=length; }
 void setSubLineLength(const int length){ Sublength=length; }
 void setAxisType(_TICKERTYPE type){ Type=type; }
 void setTextType(_TEXT_TYPE Type){ m_TextType=Type; }
 void setRangeBeg(const double &Value);
 void setRangeEnd(const double &Value);
 void setRange(const double &BegValue,const double &EndValue);
 void moveRange(const double &Value);//根據(jù)數(shù)值偏移,正數(shù)往前,負(fù)數(shù)往后
 void moveRangePercent(const double &Value);//根據(jù)百分比偏移,正數(shù)往前,負(fù)數(shù)往后
 void setZoom(const double value);//根據(jù)中心值進(jìn)行縮放,大于1表示放大,小于1表示縮小
 int getMainLineCount(){ return MainLineCount; }
 int getSubLineCount(){ return SubLineCount; }
 int getMainLineLength(){ return Mainlength; }
 int getSubLineLength(){ return Sublength; }
 _TICKERTYPE getAxisType(){ return Type; }
 double getRangeBeg(){ return m_RangeBeg; }
 double getRangeEnd(){ return m_RangeEnd; }
 double getRangeMidvalue(){ return (m_RangeBeg+(m_RangeEnd-m_RangeBeg)/2.0); }//獲取軸的中心值
 _Scale &getScale(){ return m_Scale; }
 void InitScale();
 void setScaleCoor(const double scaleFactor);//根據(jù)siteVal左邊點進(jìn)行縮放
 _TEXT_TYPE getTextType(){ return m_TextType; }
protected:
 int MainLineCount;
 int SubLineCount;
 int Mainlength;
 int Sublength;
 double m_RangeBeg;
 double m_RangeEnd;
 _TICKERTYPE Type;
 _TEXT_TYPE m_TextType;
 _Scale m_Scale;
private:
friend class CoorAxis;
};
#endif // ADDPOINT_H

頭文件mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qtimer.h"
#include "plot.h"
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
 Q_OBJECT
public:
 MainWindow(QWidget *parent = nullptr);
 ~MainWindow();
public slots:
 void slots_TimeOut();
 void slots_Refresh();
 void slots_UpdateTrack();
protected:
 QTimer *m_Timer;
 QTimer *m_TimerRefresh;
 CurveWid *m_Curve;
 QVector<QLabel *> m_labList;
 bool IsAddOk=false;
private:
 Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

c文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include <QDebug>
#include "qgridlayout.h"
#include "math.h"
#include "qpainter.h"
#include <QVBoxLayout>
#include <QGridLayout>
#define _POINTCOUNT 50000
MainWindow::MainWindow(QWidget *parent)
 : QMainWindow(parent)
 , ui(new Ui::MainWindow)
{
 ui->setupUi(this);
 ui->statusbar->hide();

 ui->centralwidget->setStyleSheet("QWidget{background-color: rgb(0, 0, 0);}");
 m_Curve=new CurveWid;
 connect(m_Curve->m_Plot,&Plot::sig_UpdateTrack,this,&MainWindow::slots_UpdateTrack);
 m_Timer=new QTimer(this);
 m_TimerRefresh=new QTimer(this);
 m_Timer->start(100);
 m_TimerRefresh->start(100);
 connect(m_Timer,&QTimer::timeout,this,&MainWindow::slots_TimeOut);
 connect(m_TimerRefresh,&QTimer::timeout,this,&MainWindow::slots_Refresh);
 m_Curve->m_AxisL->ticker()->setRange(-100,1200);
 m_Curve->m_AxisR->ticker()->setRange(-100,600);
 m_Curve->m_AxisX->ticker()->setRange(-100,_POINTCOUNT*0.01);
 qint64 Time=QDateTime::currentMSecsSinceEpoch();
 m_Curve->m_AxisX->ticker()->setTextType(_TEXT_TYPE::_TimeMs);
// m_Curve->m_AxisX->ticker()->setRange(Time-600000,Time);
 QGridLayout *G_layout=new QGridLayout;
 G_layout->setVerticalSpacing(3);
 G_layout->setContentsMargins(0,0,0,0);
 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
 for(int i=0;i<16;i++)
 {
  QLabel *labValue=new QLabel;
  labValue->setText(QString("Qlabel %1").arg(i+1));
  labValue->setAlignment(Qt::AlignCenter);
  labValue->setStyleSheet("QLabel{color:rgb(0, 122, 255);}");
  labValue->setFixedHeight(36);
  G_layout->addWidget(labValue,i/8,i%8);
  QColor color=QColor(qrand() % 256, qrand() % 256, qrand() % 256);
  int r,g,b;
  color.getRgb(&r,&g,&b);
  labValue->setStyleSheet(QString("QLabel{ color:rgb(%0,%1,%2);}").arg(r).arg(g).arg(b));
  m_labList.append(labValue);
  m_Curve->m_Plot->addGraph();
  m_Curve->m_Plot->Graph(i)->setColor(color);
  m_Curve->m_Plot->Graph(i)->setPointCountMax(_POINTCOUNT);
  if((i%2)!=0){
m_Curve->m_Plot->Graph(i)->setAxisType(_TICKERTYPE::YAxis_R);
  }else{
m_Curve->m_Plot->Graph(i)->setAxisType(_TICKERTYPE::YAxis_L);
  }
 }
 QVBoxLayout *V_layout=new QVBoxLayout;
 V_layout->setContentsMargins(0,0,0,0);
 V_layout->addWidget(m_Curve);
 V_layout->addLayout(G_layout);
 ui->centralwidget->setLayout(V_layout);

 for(int i=0;i<_POINTCOUNT*0.01;i++){
  slots_TimeOut();
 }
 IsAddOk=true;
}
MainWindow::~MainWindow()
{
 delete ui;
}
void MainWindow::slots_TimeOut()
{
 double w = (3.14/100)*5;  //w為角速度 ,可以理解為波浪的密度,越大密度越大
 double A = 40; //  A表示振幅,可以理解為水波的高度,越大高度越高
 static double x;
 x++;
 double waveY = (double)(A * sin(w * x ));// waveY隨著x的值改變而改變,從而得到正弦曲線
 static double count=0;
 count+=1;
 qint64 Time=QDateTime::currentMSecsSinceEpoch();
 for(int i=0;i<m_Curve->m_Plot->getGraphCount();i++)
 {
  int num = qrand()%(200-100)+100;//產(chǎn)生300-500范圍的隨機歲
  float data=0;//除以10獲取 30.0到50.0的隨機數(shù)
  data+=80*i+num;
//  m_Curve->m_Plot->Graph(i)->addData(count,data);
  m_Curve->m_Plot->Graph(i)->addData(count,waveY+80*i);
 }
 if(IsAddOk)
 {
  if(count>m_Curve->m_AxisX->ticker()->getRangeEnd())
  {
m_Curve->m_AxisX->ticker()->moveRange(count-m_Curve->m_AxisX->ticker()->getRangeEnd());
  }
 }
}
void MainWindow::slots_Refresh()
{
 m_Curve->reUpdateAll();
}
void MainWindow::slots_UpdateTrack()
{
 for(int i=0;i<m_Curve->m_Plot->getGraphCount();i++){
  m_labList[i]->setText(QString::number(m_Curve->m_Plot->Graph(i)->getTrackValue().Value,'f',2));
 }
}

源碼下載

工程:TestCurve
鏈接: 源碼下載

到此這篇關(guān)于Qt自定義Plot實現(xiàn)曲線繪制的文章就介紹到這了,更多相關(guān)Qt自定義曲線繪制內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部