示例,创建一个 TimeDomainPlot 类
TimeDomainPlot.h
#ifndef TIMEDOMAINPLOT_H
#define TIMEDOMAINPLOT_H
#include "qcustomplot.h"
#include
#include
class TimeDomainPlot: public QQuickPaintedItem
{
public:
explicit TimeDomainPlot(QQuickItem* parent = nullptr);
~TimeDomainPlot();
const static int DATA_SIZE;
const static double XAXIS_RANGE_START;
const static double XAXIS_RANGE_END;
virtual void paint(QPainter *painter);
void setVoltageGraphData(const QVector &keys, const QVector &values);
void setCurrentGraphData(const QVector &keys, const QVector &values);
void setVoltageRange(double min, double max);
void setCurrentRange(double min, double max);
void replot();
private:
QCustomPlot *_customPlot;
QCPGraph* _voltageGraph;
QCPGraph* _currentGraph;
};
#endif // TIMEDOMAINPLOT_H
TimeDomainPlot.cpp
#include "TimeDomainPlot.h"
#include
const int TimeDomainPlot::DATA_SIZE = 512;
const double TimeDomainPlot::XAXIS_RANGE_START = 0;
const double TimeDomainPlot::XAXIS_RANGE_END = 400;
TimeDomainPlot::TimeDomainPlot(QQuickItem *parent): QQuickPaintedItem(parent)
{
_customPlot = new QCustomPlot();
_voltageGraph = _customPlot->addGraph();
_currentGraph = _customPlot->addGraph(_customPlot->xAxis, _customPlot->yAxis2);
//设置颜色
_voltageGraph->setPen(QPen(Qt::red));
_currentGraph->setPen(QPen(Qt::blue));
//设置Y轴范围
_customPlot->yAxis->setNumberFormat("gbc");/* g 灵活的格式,b 漂亮的指数形式,c 乘号改成 x */
_customPlot->yAxis->setNumberPrecision(1);/* 精度 1 */
_customPlot->xAxis->setRange(XAXIS_RANGE_START, XAXIS_RANGE_END);
_customPlot->yAxis2->setNumberFormat("gbc");/* g 灵活的格式,b 漂亮的指数形式,c 乘号改成 x */
_customPlot->yAxis2->setNumberPrecision(1);/* 精度 1 */
_customPlot->yAxis2->setVisible(true);
//x轴名字
_customPlot->xAxis->setLabel("时间 / ms");
//Y轴名字
_customPlot->yAxis->setLabel("电压 / V");
_customPlot->yAxis->setTickLabelColor("red");
_customPlot->yAxis->setLabelColor("red");
_customPlot->yAxis2->setLabel("电流 / mA");
_customPlot->yAxis2->setTickLabelColor("blue");
_customPlot->yAxis2->setLabelColor("blue");
}
TimeDomainPlot::~TimeDomainPlot()
{
delete _customPlot;
}
void TimeDomainPlot::paint(QPainter *painter)
{
_customPlot->setGeometry(0,0,this->width(),this->height());
painter->drawPixmap(0,0,this->width(),this->height(), _customPlot->toPixmap());
}
void TimeDomainPlot::setVoltageGraphData(const QVector &keys, const QVector &values)
{
_voltageGraph->setData(keys, values);
}
void TimeDomainPlot::setCurrentGraphData(const QVector &keys, const QVector &values)
{
_currentGraph->setData(keys, values);
}
void TimeDomainPlot::setVoltageRange(double min, double max)
{
_customPlot->yAxis->setRange(min, max);
}
void TimeDomainPlot::setCurrentRange(double min, double max)
{
_customPlot->yAxis2->setRange(min, max);
}
void TimeDomainPlot::replot()
{
update(QRect(x(),y(),width(), height()));
}
main.cpp:
#include
#include
#include
#include "TimeDomainPlot.h"
//#include "DataSource.h"
#include "QQuickView"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickView viewer;
qmlRegisterType("myqml",1,0,"TimeDomainPlot");
QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
viewer.setTitle(QStringLiteral("test"));
// DataSource dataSource(&viewer);
// viewer.rootContext()->setContextProperty("dataSource", &dataSource);
viewer.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.show();
return app.exec();
}
main.qml
import QtQuick 2.9
import myqml 1.0
Item {
id: root
width: 1024
height: 600
visible: true
TimeDomainPlot {
id: timeDomainChart
x:0;y:0;width: root.width;height: root.height
}
}
此时编译运行即可看到图表添加并渲染完成。
DataSource.h
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include
#include "TimeDomainPlot.h"
QT_BEGIN_NAMESPACE
class QQuickView;
QT_END_NAMESPACE
class DataSource : public QObject
{
Q_OBJECT
public:
static const int DATA_SIZE;
public:
explicit DataSource(QQuickView *appViewer, QObject *parent = 0);
~DataSource();
Q_SIGNALS:
public slots:
void generateData();
void updateTimeDomain(TimeDomainPlot *plot);
private:
QQuickView *m_appViewer;
QVector m_timeDomainX;
QVector m_timeDomainV;
QVector m_timeDomainI;
};
#endif // DATASOURCE_H
DataSource.cpp
#include "DataSource.h"
#include
#include
#include
#include
#include
#include
Q_DECLARE_METATYPE(TimeDomainPlot *)
const int DataSource::DATA_SIZE = TimeDomainPlot::DATA_SIZE;
DataSource::DataSource(QQuickView *appViewer, QObject *parent) :
QObject(parent),
m_appViewer(appViewer)
{
qRegisterMetaType();
m_timeDomainX.resize(DATA_SIZE);
m_timeDomainV.resize(DATA_SIZE);
m_timeDomainI.resize(DATA_SIZE);
}
DataSource::~DataSource()
{
}
void DataSource::updateTimeDomain(TimeDomainPlot *plot)
{
if (plot) {
QVector &pointX = m_timeDomainX;
QVector &pointY = m_timeDomainV;
auto min = pointY[0];
auto max = pointY[0];
for (auto point : pointY)
{
min = point < min ? point : min;
max = point > max ? point : max;
}
plot->setVoltageGraphData(pointX,pointY);
plot->setVoltageRange(2 * min - max, max);
pointY = m_timeDomainI;
min = pointY[0];
max = pointY[0];
for (auto point : pointY)
{
min = point < min ? point : min;
max = point > max ? point : max;
}
plot->setCurrentGraphData(pointX,pointY);
plot->setCurrentRange(min, 2 * max - min);
plot->replot();
}
}
void DataSource::generateData()
{
for (int j(0); j < DATA_SIZE; j++) {
double x(0);
double y(0);
double y2(0);
y = qSin(M_PI / 32 * j) + 0.5 + QRandomGenerator::global()->generateDouble();
y2 = qSin(M_PI / 32 * (j + 5)) + 0.5 + QRandomGenerator::global()->generateDouble();
x = (j * 400) / (DATA_SIZE - 1);
m_timeDomainX[j] = x;
m_timeDomainV[j] = y;
m_timeDomainI[j] = y2;
}
}
DataSource dataSource(&viewer);
viewer.rootContext()->setContextProperty("dataSource", &dataSource);
Timer {
id: refreshTimer
interval: 1 / 1 * 1000 // 1 Hz
running: root.running
repeat: true
onTriggered: {
dataSource.generateData()
dataSource.updateTimeDomain(timeDomainChart)
}
}