QChart雙Y軸實時更新曲線圖

QChart雙Y軸笑窜,X軸設(shè)置時間軸

前言

工作上需要做一個雙Y軸的折線圖致燥,除了看QT的相關(guān)類的文檔,找到的資料不多怖侦,所以記錄下來篡悟。

準(zhǔn)備

首先,通過QT的幫助文檔了解下QChart匾寝、QSplineSeries(或者其他的Series類)搬葬、QValueAxis等類的描述,翻譯用的是有道的在線翻譯艳悔,自己再稍微修改一下不通順的地方急凰。
QChart
The QChart class manages the graphical representation of the chart's series, legends, and axes.
QChart類管理圖表中的線、圖例和軸的圖形表示猜年。
QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical representation of different types of series and other chart related objects like legend and axes. To simply show a chart in a layout, the convenience class QChartView can be used instead of QChart. In addition, line, spline, area, and scatter series can be presented as polar charts by using the QPolarChart class.
QChart是一個可以在QGraphicsScene中顯示的QGraphicsWidget抡锈。它管理不同類型的系列和其他圖表相關(guān)對象(如圖例和軸)的圖形表示。要簡單地在布局中顯示圖表乔外,可以使用便利類QChartView代替QChart床三。此外,直線杨幼、平滑曲線撇簿、面積和散射圖可以通過QPolarChart類來表示為極坐標(biāo)圖。
QSplineSeries
The QSplineSeries class presents data as spline charts.
QSplineSeries類將數(shù)據(jù)表示為平滑曲線圖差购。
A spline series stores the data points and the segment control points needed by QPainterPath to draw a spline. The control points are automatically calculated when the data changes. The algorithm computes the points so that the normal spline can be drawn.
一個spline series存儲QPainterPath繪制平滑曲線所需的數(shù)據(jù)點和段控制點四瘫。當(dāng)數(shù)據(jù)發(fā)生變化時,控制點會自動計算欲逃。該算法對點進行計算找蜜,以便繪制平滑曲線。
QValueAxis
QValueAxis class adds values to a chart's axes.
QValueAxis類將值添加到圖表的軸中稳析。
A value axis can be set up to show an axis line with tick marks, grid lines, and shades. The values on the axis are drawn at the positions of tick marks.
可以設(shè)置一個值軸來顯示帶有標(biāo)記洗做、網(wǎng)格線和陰影的軸線弓叛。在軸上的值是在標(biāo)記的位置繪制的。
QDateTimeAxis
The QDateTimeAxis class adds dates and times to a chart's axis.
QDateTimeAxis類將日期和時間添加到圖表的軸中诚纸。
QDateTimeAxis can be set up to show an axis line with tick marks, grid lines, and shades. The labels can be configured by setting an appropriate DateTime format. QDateTimeAxis works correctly with dates from 4714 BCE to 287396 CE. For other limitiations related to QDateTime, see QDateTime documentation.
可以設(shè)置QDateTimeAxis來顯示帶有標(biāo)記標(biāo)記邪码、網(wǎng)格線和陰影的軸線∫澹可以通過設(shè)置適當(dāng)?shù)腄ateTime格式來配置軸線上顯示的值。QDateTimeAxis可以表示公元前4714年到公元287396年之間的時間奴潘。關(guān)于其他與QDateTime相關(guān)的信息旧烧,請參閱QDateTime文檔。
Note : QDateTimeAxis is disabled on platforms that define qreal as float.
注意 :在將qreal定義為float的平臺上禁用QDateTimeAxis画髓。
關(guān)于設(shè)置雙Y軸的比較重要的的函數(shù)是QChart的 addSeries掘剪,addAxis這兩個函數(shù),前者是添加線到QChart中奈虾,后者是添加坐標(biāo)軸到指定的位置夺谁。還有QSplineSeriesattachAxis函數(shù)。QT文檔中的描述如下:
void QChart::addSeries(QAbstractSeries *series)
Adds the series series to the chart and takes ownership of it.
將series添加到chart中肉微,并且chart獲得series的所有權(quán)匾鸥,即chart成為series的parent。
Note : A newly added series is not attached to any axes by default, not even those that might have been created for the chart using createDefaultAxes() before the series was added to the chart. If no axes are attached to the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other series that have properly attached axes, so always make sure you either call createDefaultAxes() after a series has been added or explicitly attach axes for the series.
注意 : 默認(rèn)情況下碉纳,新添加的series不會附加到任何軸上勿负,即使是那些在series添加到圖表之前使用chart的createDefaultAxes()函數(shù)為圖表創(chuàng)建的軸。如果在顯示圖表之前沒有附加任何坐標(biāo)軸到新添加的series上劳曹,那么這個數(shù)列就會被繪制出來奴愉,就好像它的坐標(biāo)軸的范圍恰好與這個series對應(yīng)于圖表的繪圖區(qū)域一樣。如果同一個圖表還顯示了其他附加了軸的series铁孵,那么這可能會繪制出令人困惑畫面锭硼,所以一定要確保在添加了series之后再調(diào)用createDefaultAxes(),或者顯式地為該series附加軸蜕劝。
void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
Adds the axis axis to the chart aligned as specified by alignment. The chart takes the ownership of the axis.
將坐標(biāo)軸添加到圖表中的指定的位置(左邊檀头,下方,右邊熙宇,上方)鳖擒。這個chart獲得坐標(biāo)軸的所有權(quán)。
bool QAbstractSeries::attachAxis(QAbstractAxis *axis)
Attaches the axis specified by axis to the series.
將指定的坐標(biāo)軸附加給series烫止。
Returns true if the axis was attached successfully, false otherwise.
如果成功蒋荚,返回true,否則馆蠕,返回false
Note : If multiple axes of the same orientation are attached to the same series, they will have the same minimum and maximum values.
注意 :如果同一系列上有多個相同方向的軸期升,它們的最小值和最大值是相同的惊奇。

編碼實現(xiàn)

接下來開始寫代碼,打開QT播赁,我的是QT5.11颂郎,新建工程,在.pro文件里增加

QT+=charts

在源文件里添加QChart的頭文件

#include <QtCharts>

#include <QtCharts/QSplineSeries>

在.cpp文件里增加命名空間

QT_CHARTS_USE_NAMESPACE       
//或者 using namespace QtCharts;

然后在QT設(shè)計師里往窗口添加一個Graphics View容为,然后提升為QChartView乓序,


提升Graphics View

然后是編輯源文件,這里我就直接上代碼了坎背,代碼里寫有注釋替劈。
mainwindow.h文件

#ifndef MAINWINDOW_H

#define MAINWINDOW_H



#include <QMainWindow>

#include <QtCharts>

#include <QtCharts/QSplineSeries>

#include <QDateTime>

?

?

namespaceUi{

classMainWindow;

}

?

classMainWindow:publicQMainWindow

{

Q_OBJECT

?

public:

explicitMainWindow(QWidget*parent=0);

~MainWindow();

?

/*menbers**************************************************************************************/

//聲明QChart的實例,QSplineSeries的實例

QChart*chart;

QSplineSeries*series1;

QSplineSeries*series2;

//聲明timer

QTimer*timer;

?

/*funcions **************************************************************************************/

//聲明劃線的函數(shù)和初始化QChart的函數(shù)

voiddrawLine();

voidinitChart();

?

publicslots:

/*slot function**********************************************************************************/

//聲明timer的槽函數(shù)

voidtimerDeal();

?

private:

Ui::MainWindow*ui;

};

?

#endif // MAINWINDOW_H

?mainwindow.cpp文件

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include <math.h>

#include <QThread>

?

?

QT_CHARTS_USE_NAMESPACE

MainWindow::MainWindow(QWidget*parent) :

QMainWindow(parent),

ui(newUi::MainWindow)

{

ui->setupUi(this);

//初始化QChart

initChart();

?

//設(shè)置timer得滤,槽連接到

timer=newQTimer();

timer->setInterval(400);

connect(timer,SIGNAL(timeout()),this,SLOT(timerDeal()));

timer->start();

}

?

MainWindow::~MainWindow()

{

deleteui;

}

?

//實現(xiàn)QChart的初始化函數(shù)

voidMainWindow::initChart()

{

//初始化QChart的實例

chart=newQChart();

?

//初始化兩個QSplineSeries的實例

series1=newQSplineSeries();

series2=newQSplineSeries();

//設(shè)置兩條曲線的名稱

series1->setName("series1");

series2->setName("series2");

?

//把曲線添加到QChart的實例chart中

chart->addSeries(series1);

chart->addSeries(series2);

?

//聲明并初始化X軸陨献、兩個Y軸

QDateTimeAxis*axisX=newQDateTimeAxis();

//    QValueAxis *axisX = new QValueAxis();

QValueAxis*axisY_1=newQValueAxis();

QValueAxis*axisY_2=newQValueAxis();

//設(shè)置坐標(biāo)軸顯示的范圍

axisX->setMin(QDateTime::currentDateTime().addSecs(-60*1));

axisX->setMax(QDateTime::currentDateTime().addSecs(0));

axisY_1->setMin(0);

axisY_1->setMax(18);

axisY_2->setMin(0);

axisY_2->setMax(18);

?

//設(shè)置坐標(biāo)軸上的格點

axisY_1->setTickCount(7);

axisY_2->setTickCount(11);

//設(shè)置坐標(biāo)軸顯示的名稱

axisX->setTitleText("X軸");

axisY_1->setTitleText("axisY_1-series1");

axisY_2->setTitleText("axisY_2-series2");

//設(shè)置坐標(biāo)軸的顏色,粗細(xì)懂更,設(shè)置網(wǎng)格不顯示

axisY_1->setLinePenColor(QColor(Qt::darkBlue));

axisY_1->setGridLineColor(QColor(Qt::darkBlue));

axisY_2->setLinePenColor(QColor(Qt::darkGreen));

axisY_2->setGridLineColor(QColor(Qt::darkGreen));

axisY_1->setGridLineVisible(false);

axisY_2->setGridLineVisible(false);

QPenpenY1(Qt::darkBlue,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin);

QPenpenY2(Qt::darkGreen,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin);

axisY_1->setLinePen(penY1);

axisY_2->setLinePen(penY2);

?

//把坐標(biāo)軸添加到chart中眨业,

//addAxis函數(shù)的第二個參數(shù)是設(shè)置坐標(biāo)軸的位置,

//只有四個選項沮协,下方:Qt::AlignBottom龄捡,左邊:Qt::AlignLeft,右邊:Qt::AlignRight慷暂,上方:Qt::AlignTop

chart->addAxis(axisX,Qt::AlignBottom);

chart->addAxis(axisY_1,Qt::AlignLeft);

chart->addAxis(axisY_2,Qt::AlignRight);

?

//把曲線關(guān)聯(lián)到坐標(biāo)軸

series1->attachAxis(axisX);

series1->attachAxis(axisY_1);

series2->attachAxis(axisX);

series2->attachAxis(axisY_2);

?

//把chart顯示到窗口上

ui->graphicsView->setChart(chart);

?

}

?

//實現(xiàn)畫線函數(shù)墅茉,動態(tài)更新

voidMainWindow::drawLine()

{

//每增加一個點改變X軸的范圍,實現(xiàn)曲線的動態(tài)更新效果

QDateTimebjtime=QDateTime::currentDateTime();

qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));

chart->axisX()->setMax(QDateTime::currentDateTime().addSecs(0));

?

//當(dāng)曲線上最早的點超出X軸的范圍時呜呐,剔除最早的點就斤,

if(series1->count()>119)

   {

series1->removePoints(0,series1->count()-119);

   }

if(series2->count()>119)

   {

series2->removePoints(0,series2->count()-119);

   }

?

intY1=qrand()%9;//隨機生成0到9的隨機數(shù)

intY2=9+qrand()%9;//隨機生成9到18的隨機數(shù)

//增加新的點到曲線末端

series1->append(bjtime.toMSecsSinceEpoch(),Y1);

series2->append(bjtime.toMSecsSinceEpoch(),Y2);

?

}

//實現(xiàn)timer的槽函數(shù)

voidMainWindow::timerDeal()

{

//定時畫曲線

drawLine();

}

?最終效果,曲線和X軸的范圍隨著時間實時更新蘑辑。


最終效果

總結(jié)

了解了以后洋机,就覺得實現(xiàn)這個效果并不難,關(guān)鍵函數(shù)就那幾個洋魂。雖說不難绷旗,也算是解決了一個問題,獲得了成長副砍。

聲明

本文中的代碼均為本人所寫衔肢,本文亦是本人原創(chuàng),轉(zhuǎn)載請注明出處豁翎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末角骤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子心剥,更是在濱河造成了極大的恐慌邦尊,老刑警劉巖背桐,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蝉揍,居然都是意外死亡链峭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門又沾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弊仪,“玉大人,你說我怎么就攤上這事杖刷『扯蹋” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵挺勿,是天一觀的道長。 經(jīng)常有香客問我喂柒,道長不瓶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任灾杰,我火速辦了婚禮蚊丐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艳吠。我一直安慰自己麦备,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布昭娩。 她就那樣靜靜地躺著凛篙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栏渺。 梳的紋絲不亂的頭發(fā)上呛梆,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音磕诊,去河邊找鬼填物。 笑死,一個胖子當(dāng)著我的面吹牛霎终,可吹牛的內(nèi)容都是我干的滞磺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼莱褒,長吁一口氣:“原來是場噩夢啊……” “哼击困!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起广凸,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤沛励,失蹤者是張志新(化名)和其女友劉穎责语,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體目派,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡坤候,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了企蹭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片白筹。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谅摄,靈堂內(nèi)的尸體忽然破棺而出徒河,到底是詐尸還是另有隱情,我是刑警寧澤送漠,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布顽照,位于F島的核電站,受9級特大地震影響闽寡,放射性物質(zhì)發(fā)生泄漏代兵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一爷狈、第九天 我趴在偏房一處隱蔽的房頂上張望植影。 院中可真熱鬧,春花似錦涎永、人聲如沸思币。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谷饿。三九已至,卻和暖如春妈倔,著一層夾襖步出監(jiān)牢的瞬間各墨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工启涯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贬堵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓结洼,卻偏偏與公主長得像黎做,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子松忍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容