一个简单的折线图
打开欢迎界面中的示例,搜索linechart,点击Running the Example,打开示例。
1、改pro工程文件
Qt Charts
作为一个独立的模块,在使用前需要在项目的pro
文件中添加:
QT += charts
2、包含头文件,并引用qt chart空间命名
// 包含line chart需要的头文件
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
// 引用命名空间
QT_CHARTS_USE_NAMESPACE
3、创建QLineSeries并添加数据
折线图的实现需要创建一个QLineSeries
对象用于保存和绘制折线数据:
QLineSeries *series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) <<QPointF(20, 2);
4、创建QChart用于显示数据
创建好series
后,需要创建一个QChart
实例并关联series
,创建坐标才能将数据显示出来:
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Simple line chart example");
5、创建QChartView对象并显示图表
这里创建QChartView
对象是为了将最终结果显示到界面,如果不想用QChartView
,也可以选择QGraphicsView scene
来显示。
QChartView *chartView = new QChartView(chart);
// 开启抗锯齿,让显示效果更好
chartView->setRenderHint(QPainter::Antialiasing);
官方源码
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
QT_CHARTS_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//![1]
QLineSeries *series = new QLineSeries();
//![1]
//![2]
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);
//![2]
//![3]
QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Simple line chart example");
//![3]
//![4]
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
//![4]
//![5]
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(400, 300);
window.show();
//![5]
return a.exec();
}
绘制动态折线图
1、使用QChart::scroll(qreal dx, qreal dy)函数
使用定时器,连接定时器timeout()信号、handleTimeout()槽函数,每过1000ms进入槽函数处理。
槽函数:
void Chart::handleTimeout()
{
qreal x = plotArea().width() / m_axis->tickCount();
qreal y = (m_axis->max() - m_axis->min()) / m_axis->tickCount();
m_x += y;
m_y = qrand() % 5 - 2.5;
m_series->append(m_x, m_y);
scroll(x, 0);
if (m_x == 100)
m_timer.stop();
}
scroll()函数可以滚动表格,根据可见范围的特定距离。
2、改变横坐标轴的范围
QDateTimeAxis::setRange(QDateTime min, QDateTime max)函数可以设置时间横坐标轴的范围,从而达到折线图动态横移的效果。
void MainWindow::timerEvent(QTimerEvent *event)
{
static int i = 0;
if(i++ == 10)
{
i = 0;
qDebug() << "timer";
}
QDateTime t(QDateTime::currentDateTime());
dseries->append(t.toMSecsSinceEpoch(),(qrand()%10));
QDateTime xMax;// 设置时间坐标轴范围
xMax = QDateTime::currentDateTime();
if(xMax > daxisX->max())
{
QDateTime xMin;
xMin = xMax.addSecs(qint64(-20));
daxisX->setRange(xMin,xMax);
}
}
------------------------------------------------------源文件------------------------------------
头文件mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void paintEvent(QPaintEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp文件
#include "mainwindow.h"
#include <QDebug>
int xAxisData[10];
int yAxisData[10];
int oldxData[10];
int oldyData[10];
QList<QPointF> pointList;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTimer *timer = new QTimer(this);
this->startTimer(1000);
// 按键
button = new QPushButton(this);
button->setText("KEY");
button->move(400,20);
connect(button,&QPushButton::clicked,this,&this->button_slot);
// 按键1
button1 = new QPushButton(this);
button1->setText("KEY1");
button1->move(400,40);
connect(button1,&QPushButton::clicked,this,&this->button1_slot);
// 按键2
button2 = new QPushButton(this);
button2->setText("KEY2");
button2->move(400,70);
connect(button2,&QPushButton::clicked,this,&this->button2_slot);
// 设置轴坐标
axisX = new QValueAxis;
axisX->setRange(0, 10);
axisX->setTickCount(10); // 设置轴坐标网格数
axisX->setLabelFormat("%.1f");
// 设置轴坐标
axisY = new QValueAxis;
axisY->setRange(0, 10);
axisY->setTickCount(5); // 设置轴坐标网格数
axisY->setLabelFormat("%d");
QPen pen;
pen.setWidth(3);
pen.setColor(Qt::red);
series = new QLineSeries;
series->setPen(pen);
chart = new QChart;
chart->addSeries(series);
chart->setTitle("坐标图");
chart->setAxisX(axisX,series);
chart->setAxisY(axisY,series);
chart->legend()->hide(); // 隐藏图例
chartView = new QChartView(chart,this);
chartView->setRenderHint(QPainter::Antialiasing);
chartView->resize(400,200);
chartView->move(20,20);
// 设置轴坐标
daxisX = new QDateTimeAxis;
daxisX->setTickCount(5); // 设置轴坐标网格数
daxisX->setFormat("h:mm:ss");
QDateTime xMin,xMax;// 设置时间坐标轴范围
xMin = QDateTime::currentDateTime();
xMax = xMin.addSecs(20);
daxisX->setRange(xMin,xMax);
// 设置轴坐标
daxisY = new QValueAxis;
daxisY->setRange(0, 10);
daxisY->setTickCount(5); // 设置轴坐标网格数
daxisY->setLabelFormat("%d");
QPen dpen;
dpen.setWidth(3);
dpen.setColor(Qt::red);
dseries = new QLineSeries;
dseries->setPen(pen);
dchart = new QChart;
dchart->addSeries(dseries);
dchart->setTitle("坐标图");
dchart->setAxisX(daxisX,dseries);
dchart->setAxisY(daxisY,dseries);
dchart->legend()->hide(); // 隐藏图例
dchartView = new QChartView(dchart,this);
dchartView->setRenderHint(QPainter::Antialiasing);
dchartView->resize(400,200);
dchartView->move(20,260);
}
MainWindow::~MainWindow()
{
}
void MainWindow::button_slot()
{
static int j = 0, k = 0;
qDebug() << "button";
if(k == 0)
{
k = 1;
for(int i=0;i<10;i++)
{
oldxData[i] = -1 + i;
series->append(oldxData[i],oldyData[i]);
}
}
else
{
for(int i=0;i<10;i++)
{
xAxisData[i] = oldxData[i] + 1;
if(i!=9)yAxisData[i] = yAxisData[i+1];
else{
yAxisData[9] = qrand() % 10;
axisX->setRange(xAxisData[0],xAxisData[9]);
}
series->remove(oldxData[i],oldyData[i]);
series->append(xAxisData[i],yAxisData[i]);
oldxData[i] = xAxisData[i];
oldyData[i] = yAxisData[i];
}
}
}
void MainWindow::button1_slot()
{
qDebug() << "button1";
QDateTime t(QDateTime::currentDateTime());
dseries->append(t.toMSecsSinceEpoch(),(qrand()%10));
QDateTime xMax;// 设置时间坐标轴范围
xMax = QDateTime::currentDateTime();
if(xMax > daxisX->max())
{
QDateTime xMin;
xMin = xMax.addSecs(qint64(-20));
daxisX->setRange(xMin,xMax);
}
}
/* 使用list队列添加折线图的点
* 1、创建list
* 2、按下按键,添加一个QPointF点到list内,刷新series内的点
* 3、如果添加的个数大于10个需要:1)移动轴坐标 2)删除列表尾,删除曲线集的最后一个
*
*
*/
void MainWindow::button2_slot()
{
qDebug() << "button2";
static int i = 0;
QPointF p11(i,(qrand()%10));
pointList.append(p11);
series->append(p11);
if(pointList.isEmpty() == false && pointList.count() > 10)
{
series->remove(*(pointList.begin()));
pointList.removeFirst();
qreal a1 =0, a2 = 0;
a1 = pointList.back().rx();
a2 = pointList.front().rx();
axisX->setRange(a2,a1);
}
i++;
}
void MainWindow::timerEvent(QTimerEvent *event)
{
static int i = 0;
if(i++ == 10)
{
i = 0;
qDebug() << "timer";
}
QDateTime t(QDateTime::currentDateTime());
dseries->append(t.toMSecsSinceEpoch(),(qrand()%10));
QDateTime xMax;// 设置时间坐标轴范围
xMax = QDateTime::currentDateTime();
if(xMax > daxisX->max())
{
QDateTime xMin;
xMin = xMax.addSecs(qint64(-20));
daxisX->setRange(xMin,xMax);
}
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}