? ? ? ? 說在前面,本人也是近段時間剛開始學(xué)習(xí)Qt,實現(xiàn)上述功能的方法可能并不是最優(yōu),寫此篇文章也是記錄下學(xué)習(xí)的過程,也與大家分享一下。(在此先描述,后面會附上代碼)(前面說的會比較基礎(chǔ))
? ? ? ? 首先,要使用QChartView類得現(xiàn)在.pro文件中加入:(得確保你的Qt中有QtCharts,可以在qt文件夾下include文件夾中查看)
QT += charts
? ? ? ? ?同時需要在所創(chuàng)建的主窗口的.h文件下加入:
QT_BEGIN_NAMESPACE
class QChartView;
class QChart;
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
????????由于Qt6與Qt5中有些不太一樣,NAMESPACE的使用方式也有所更改,所以不同的版本得按不同的規(guī)則來。(后面對坐標(biāo)軸的建立及使用也有不一樣的地方)
????????然后在ui設(shè)計界面拖入QGraphicsView并將其提升為QChartView,或是自建類。(本人所采用的是自建類的方式,所以本文主要按自建類的方式來說明。特別強(qiáng)調(diào)下,自建類更方便采用鼠標(biāo)事件,建議使用自建類,自建類繼承QChartView即可)
? ? ? ? 本文自建類的名稱為chartview,如果沒建立則基類選擇QGraphics,提升的類名寫自建類的名稱即可。
?
? ? ? ? 最后在頭文件中加入:(其實沒啥先后順序,都執(zhí)行就行0.0)
#include <QtCharts>
? ? ? ? 就應(yīng)該可以開始建立波形圖了。建立方法如下:
? ? ? ? 首先先創(chuàng)建一個新的QChart指針、所需要畫的線的指針(折線為QLineSeries,曲線為
QSplineSeries,散點為QScatterSeries)與坐標(biāo)系指針。
QSplineSeries* line;
QChart* chart;
QValueAxis *axisX;
QValueAxis *axisY;
????????弄完這些就可以直接創(chuàng)建了圖了:
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(21, 100, 255));
m_Timer = new QTimer(this);
connect(m_Timer,SIGNAL(timeout()),this,SLOT(updata_plot()));
line = new QSplineSeries(this);
chart = new QChart();
chart->addSeries(line);
axisX = new QValueAxis(this);
axisY = new QValueAxis(this);
// line->setName("");//設(shè)置曲線名稱
line->setPen(pen);//設(shè)置曲線顏色
line->setMarkerSize(2); //點大小
line->setUseOpenGL(true);//openGl 加速
// chart->setTitle("Pressure Data");//設(shè)置圖標(biāo)標(biāo)題
chart->removeSeries(line);
chart->addSeries(line);
chart->addAxis(axisX,Qt::AlignBottom);
chart->addAxis(axisY,Qt::AlignLeft);
axisX->setRange(0,100);
axisY->setRange(0,10);
axisX->setLabelFormat("%.1f");
line->attachAxis(axisX);
line->attachAxis(axisY);
line->setPointsVisible(true);
ui->"這里是你創(chuàng)建的QChartView對象名"->setChart(chart);
? ? ? ? 大致創(chuàng)建就說到這里,主要還是說鼠標(biāo)事件。
? ? ? ? 由于是自建類,不好調(diào)用ui(如果硬要調(diào)用也是可以的,但操作比較麻煩,不推薦)
? ? ? ? 簡單做法就是直接信號與槽,即chartview下的鼠標(biāo)事件發(fā)生后發(fā)送一個信號連接MainWindow下的槽函數(shù),然后再槽函數(shù)中處理。(這里先附代碼,再說方法)
? ? ? ? chartview.h
#ifndef CHARTVIEW_H
#define CHARTVIEW_H
#include <QGraphicsView>
#include <QMouseEvent>
#include <QChartView>
#include <QWheelEvent>
class chartview : public QChartView
{
Q_OBJECT
public:
explicit chartview(QWidget *parent = nullptr);
signals:
void sendevent(QMouseEvent *ev);
void wheelevent(QWheelEvent *ev);
void relaeseevent(QMouseEvent *ev);
private slots:
void mouseMoveEvent(QMouseEvent *ev); //鼠標(biāo)移動事件
void wheelEvent(QWheelEvent *ev); //鼠標(biāo)滾動事件
void mouseReleaseEvent(QMouseEvent *ev);//鼠標(biāo)釋放事件
};
#endif // CHARTVIEW_H
????????chartview.c
#include "chartview.h"
#include <QDebug>
chartview::chartview(QWidget *parent)
: QChartView{parent}
{
}
void chartview::mouseMoveEvent(QMouseEvent *ev)
{
emit sendevent(ev);
}
void chartview::wheelEvent(QWheelEvent *ev)
{
emit wheelevent(ev);
}
void chartview::mouseReleaseEvent(QMouseEvent *ev)
{
emit relaeseevent(ev);
}
????????mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QtCharts>
#include <QTimer>
#include <QList>
#include <QWheelEvent>
#include <QMouseEvent>
QT_BEGIN_NAMESPACE
class QChartView;
class QChart;
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QTimer* m_Timer;
QLabel *label;
QSplineSeries* line;
QVector<QPointF> MV_reserve;
int max_reserve =1000;
//繪圖變量與坐標(biāo)
QChart* chart;
QValueAxis *axisX;
QValueAxis *axisY;
void creat_chartview(); //創(chuàng)建圖表視圖
public slots:
void updata_plot(); //更新圖標(biāo)視圖
void chartmove(QMouseEvent *ev);
void wheelmove(QWheelEvent *ev);
void releasemove(QMouseEvent *ev);
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
? ? ? ? mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "chartview.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_Timer = new QTimer(this);
m_Timer->start(10);
m_Timer->stop();
label = new QLabel(this);
label->setStyleSheet(QString("QLabel{color:#1564FF; font-family:\"Microsoft Yahei\"; font-size:10px; font-weight:bold;"
" background-color:rgba(21, 100, 255, 51); border-radius:4px; text-align:center;}"));
label->setFixedSize(58, 24);
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
label->hide();
creat_chartview();
connect(ui->ShowChart0,&chartview::sendevent,this,&MainWindow::chartmove); //左鍵拖動右鍵拖動與懸浮
connect(ui->ShowChart0,&chartview::wheelevent,this,&MainWindow::wheelmove); //滾動
connect(ui->ShowChart0,&chartview::relaeseevent,this,&MainWindow::releasemove);//中鍵按下
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::creat_chartview()
{
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(21, 100, 255));
connect(m_Timer,SIGNAL(timeout()),this,SLOT(updata_plot()));
line = new QSplineSeries(this);
chart = new QChart();
chart->addSeries(line);
axisX = new QValueAxis(this);
axisY = new QValueAxis(this);
// line->setName("");//設(shè)置曲線名稱
line->setPen(pen);//設(shè)置曲線顏色
line->setMarkerSize(2);//點大小
line->setUseOpenGL(true);//openGl 加速
chart->removeSeries(line);
chart->addSeries(line);
chart->addAxis(axisX,Qt::AlignBottom);
chart->addAxis(axisY,Qt::AlignLeft);
axisX->setRange(0,100);
axisY->setRange(0,10);
axisX->setLabelFormat("%.1f");
line->attachAxis(axisX);
line->attachAxis(axisY);
line->setPointsVisible(true);
ui->ShowChart0->setChart(chart);
}
void MainWindow::updata_plot()
{
double left,right,err;
QVector<QPointF> newlist;
left = axisX->min();
right= axisX->max();
err=right-left;
MV_reserve = line->points();
// qDebug()<<MV_reserve.size();
if(MV_reserve.size() == max_reserve)
{
for(int i =1 ; i<max_reserve ;i++)
{
newlist.append(QPointF(i-1,MV_reserve.at(i).y()));
}
}
else
{
newlist = MV_reserve;
if(MV_reserve.size()>=right)
{
axisX->setRange(MV_reserve.size()-err,MV_reserve.size());
}
}
newlist.append(QPointF(MV_reserve.size(),rand()%10));
line->replace(newlist);
}
void MainWindow::wheelmove(QWheelEvent *ev) //鼠標(biāo)滾動放大縮小指向區(qū)域
{
QPoint sroll = ev->angleDelta();
if(ev->position().x()>=60&&ev->position().x()<=ui->ShowChart0->width()-40
&&ev->position().y()>=80&&ev->position().y()<=ui->ShowChart0->height()-50)
{
double left,right,err;
double Currentpoint,changer,changel;
left = axisX->min();
right= axisX->max();
err=right-left;
Currentpoint = ((ev->position().x()-60)/(ui->ShowChart0->width()-100))*err+left;
if(sroll.y() > 0)
{
if(err>=10)
{
changer = right-(right-Currentpoint)*0.1;
changel = left+(Currentpoint-left)*0.1;
axisX->setRange(changel,changer);
}
}
else
{
changer = right+(right-Currentpoint)*0.1;
changel = left-(Currentpoint-left)*0.1;
if(changer>=MV_reserve.size()) {changer=MV_reserve.size();}
if(changel<=0) {changel=0; }
axisX->setRange(changel,changer);
}
}
}
void MainWindow::chartmove(QMouseEvent *ev) //鼠標(biāo)左鍵點擊拖動圖片右鍵拖動縮放相關(guān)坐標(biāo)軸
{
static QPoint last_posl,last_posr;
QPoint changepos;
QPoint now_pos;
double err,erry,left,right,height,bottom;
left = axisX->min();
right = axisX->max();
height = axisY->max();
bottom = axisY->min();
err = right-left;
erry = height-bottom;
if(ev->position().x()>=60&&ev->position().x()<=ui->ShowChart0->width()-40
&&ev->position().y()>=80&&ev->position().y()<=ui->ShowChart0->height()-50)//鼠標(biāo)懸停
{
double nearposx,posy,posx,poserrx;
int selectx;
nearposx = left + (ev->position().x()-60)/(ui->ShowChart0->width()-100)*err;
//判斷當(dāng)前距離最近的一個點
if(int(nearposx*10)%10<5)
{
selectx = int(nearposx);
}
else
{
selectx = int(nearposx+1);
}
//求出一個比較好的范圍
poserrx = (ui->ShowChart0->width()-100)/err;
if(poserrx<20)
{
poserrx/=2;
}
else
{
poserrx=10;
}
//判斷該點是否在圖中
if(line->at(selectx).y()<height+err*0.01)
{
posx = 60+((line->at(selectx).x()-left)/err)*(ui->ShowChart0->width()-100);
posy = 80+((height - line->at(selectx).y())/erry)*(ui->ShowChart0->height()-130);
if(ev->position().y()<=(posy+10)&&ev->position().y()>=(posy-10)
&&ev->position().x()<=(posx+poserrx)&&ev->position().x()>=(posx-poserrx))
{
label->setText(QString::asprintf("(%.1f,%d)", line->at(selectx).y(),(int)line->at(selectx).x()));
label->move(ev->position().x() +133, ev->position().y() +43);
label->show();
//在這生成一個qlabel
}
else
{
label->hide();
//在這隱藏生成的qlabel
}
}
if(MV_reserve.size()>=100&&ev->buttons()==Qt::LeftButton) 左鍵拖動
{
now_pos = ev->pos();
changepos = now_pos-last_posl;
last_posl = now_pos;
if(axisX->min()<=0&&changepos.x()>0)
{
axisX->setRange(0,err);
return;
}
else if(axisX->max()>=MV_reserve.size()-1&&changepos.x()<0)
{
axisX->setRange(MV_reserve.size()-err,MV_reserve.size());
return;
}
else
{
chart->scroll(-changepos.x(),changepos.y());
}
}
else
{
last_posl = ev->pos();
}
if(ev->buttons()==Qt::RightButton) 右鍵拖動
{
double changel,changer,changeh,changeb;
now_pos = ev->pos();
changepos = now_pos-last_posr;
last_posr = now_pos;
if(changepos.x()>0)
{
changel = left+err*0.01*changepos.x();
changer = right-err*0.01*changepos.x();
if((changer-changel)>=5)
{
axisX->setRange(left+err*0.01*changepos.x(),right-err*0.01*changepos.x());
}
}
else if(changepos.x()<0)
{
changel = left+err*0.01*changepos.x();
changer = right-err*0.01*changepos.x();
if(changel>=0&&changer<=MV_reserve.size())
{
axisX->setRange(changel,changer);
}
else
{
if(changel<0&&changer<=MV_reserve.size())
{
axisX->setRange(0,changer);
}
else if(changel>=0&&changer>MV_reserve.size())
{
axisX->setRange(changel,MV_reserve.size());
}
else
{
axisX->setRange(0,MV_reserve.size());
}
}
}
if(changepos.y()>0)
{
changeh = height+erry*0.01*changepos.y();
changeb = bottom-erry*0.01*changepos.y();
axisY->setRange(changeb,changeh);
}
else if(changepos.y()<0)
{
changeh = height+erry*0.01*changepos.y();
changeb = bottom-erry*0.01*changepos.y();
axisY->setRange(changeb,changeh);
}
}
else
{
last_posr = ev->pos();
}
}
}
void MainWindow::releasemove(QMouseEvent *ev) 鼠標(biāo)中鍵點擊縮小
{
if(ev->button()==Qt::MiddleButton
&&ev->position().x()>=70&&ev->position().x()<=ui->ShowChart0->width()-50
&&ev->position().y()>=90&&ev->position().y()<=ui->ShowChart0->height()-60)
{
double errx,leftx,rightx;
double erry,lefty,righty;
leftx = axisX->min();
rightx = axisX->max();
errx = rightx-leftx;
lefty = axisY->min();
righty = axisY->max();
erry = righty-lefty;
leftx-=errx*0.4;
rightx+=errx*0.4;
lefty-=erry*0.4;
righty+=erry*0.4;
if(leftx>=0&&rightx<=MV_reserve.size())
{axisX->setRange(leftx,rightx);}
else
{
if(leftx<=0&&rightx>=MV_reserve.size())
{axisX->setRange(0,MV_reserve.size());}
else if(leftx<=0)
{axisX->setRange(0,rightx);}
else
{axisX->setRange(leftx,MV_reserve.size());}
}
axisY->setRange(lefty,righty);
}
}
void MainWindow::on_pushButton_clicked()
{
if(m_Timer->isActive())
{
m_Timer->stop();
}
else
{
m_Timer->start();
}
}
? ? ? ? 左右鍵與懸停顯示都是基于mousemoveevent,左鍵平移好理解,右鍵縮放也應(yīng)該沒啥問題,里面主要是對懸停比較麻煩,按理說應(yīng)該可以用點的hover信號,但不知道為啥,這個信號的好像沒那么穩(wěn)定,所以只能自己寫,大致就是先判斷距離最近的點,再在該點周圍畫個框,判斷鼠標(biāo)是否在這個框里面,如果在,就show創(chuàng)建的label,不在就hide創(chuàng)建的label。
附上網(wǎng)盤:文章來源:http://www.zghlxwxcb.cn/news/detail-491188.html
鏈接:https://pan.baidu.com/s/1CFOA82rWkepk3-tFQ2u4Cg?
提取碼:g2uh文章來源地址http://www.zghlxwxcb.cn/news/detail-491188.html
到了這里,關(guān)于Qt6使用QChartView類與鼠標(biāo)事件實現(xiàn)波形的縮放、平移、坐標(biāo)軸單軸縮放與鼠標(biāo)懸停顯示點的數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!