我有一个收集数据的c ++类(当前只是在上限和下限之间生成的随机数)并将其打包到QVector(QPointF)中。我有一个包含ChartView的QML文件。我想在我的QML ChartView(LineSeries)中绘制收集的c ++数据,并在每次c ++中的数据收集功能完成时更新绘图。我想将收集的QVector发送到辅助c ++类来执行QML ChartView更新。
以下是各种相关文件的摘录。
data.h:
npm install
data.cpp:
#ifndef DATA_H
#define DATA_H
#include <QObject>
#include <QTimer>
#include <QtCore/QObject>
#include <QAbstractSeries>
#include <QXYSeries>
class Data : public QObject
{
Q_OBJECT
Q_PROPERTY(QVector<int> wVector READ wVector NOTIFY wVectorChanged)
public:
Data();
Q_PROPERTY(float wValue READ wValue NOTIFY wValueChanged)
float wValue(){return this->m_wValue;}
QVector<int> wVector(){return m_wVector;}
signals:
void wValueChanged();
void wVectorChanged();
private slots:
void wTimeout();
public slots:
private:
float m_wValue;
QTimer * m_wTimer;
QVector<int> m_wVector;
QList<QVector<QPointF> > m_data;
};
#endif // DATAD_H
chart.h:
#include "data.h"
#include "chart.h"
#include <QDebug>
#include <iostream>
#include <QTimer>
#include <QtCharts/QXYSeries>
#include <QtCharts/QAreaSeries>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QtMath>
Data::Data()
{
this->m_wTimer = new QTimer(this);
this->m_wTimer->setInterval((1000 / 5));
connect(this->m_wTimer, &QTimer::timeout, this, &Data::wTimeout);
this->m_wTimer->start();
}
void Data::wTimeout()
{
int HIGH = 100;
int LOW = 0;
this->m_wValue = rand() % (HIGH - LOW + 1) + LOW;
if (m_wVector.size() >= 5 && !m_wVector.isEmpty())
m_wVector.removeFirst();
this->m_wVector.append(m_wValue);
m_data.clear();
QVector<QPointF> dataStore;
for (int i(0); i < m_wVector.size(); i++) {
dataStore.append(QPointF(i+1, m_wVector[i]));
}
m_data.append(dataStore);
emit wValueChanged();
//SEND m_data to Chart.update() here??
}
chart.cpp:
#ifndef CHART_H
#define CHART_H
#include <QtCore/QObject>
#include <QtCharts/QAbstractSeries>
#include <QXYSeries>
class QTimer;
QT_CHARTS_USE_NAMESPACE
class Chart : public QObject
{
Q_OBJECT
public:
ConfigurationChart();
Q_INVOKABLE void setSeries(QAbstractSeries *series);
public slots:
void update();
private:
QList<QVector<QPointF> > m_data;
int m_index;
QXYSeries *mSeries;
QTimer *timer;
};
#endif // CHART_H
main.cpp中:
#include "chart.h"
#include <QtCharts/QXYSeries>
#include <QtCharts/QAreaSeries>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QtCore/QDebug>
#include <QtCore/QtMath>
#include <QTimer>
QT_CHARTS_USE_NAMESPACE
Q_DECLARE_METATYPE(QAbstractSeries *)
Q_DECLARE_METATYPE(QAbstractAxis *)
Chart::Chart()
{
qRegisterMetaType<QAbstractSeries*>();
qRegisterMetaType<QAbstractAxis*>();
}
void Chart::update()//Need to pass the m_data QList<QVector<QPointF>> parameter here??
{
if (mSeries) {
m_index++;
if (m_index > m_data.count() - 1)
m_index = 0;
QVector<QPointF> points = m_data.at(m_index);
mSeries->replace(points);
}
}
void Chart::setSeries(QAbstractSeries *series)
{
//I don't know how this is called, nor how this actually establishes a link to the QML chart??
if (series) {
mSeries = static_cast<QXYSeries *>(series);
}
}
main.qml:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickItem>
#include <thread>
#include <chrono>
#include <QDebug>
#include <time.h>
#include <iostream>
#include <typeinfo>
#include <QtCharts>
#include <QtQuick/QQuickView>
#include "data.h"
#include "hart.h"
using namespace std;
using namespace QtCharts;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("Data"), new Data());
engine.rootContext()->setContextProperty(QStringLiteral("Chart"), new Chart());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
我的问题:如何将chart.cpp连接到QML LineSeries以绘制QML ChartView中的chart.cpp数据(从data.cpp接收)?
我正在使用Qt5.9.2。
答案 0 :(得分:0)
没有必要使用C ++中的系列(我认为图表类是不必要的),数据可以直接更新,如下所示:
<强> data.h 强>
#ifndef DATA_H
#define DATA_H
#include <QObject>
#include <QPointF>
#include <QTimer>
class Data : public QObject
{
Q_OBJECT
Q_PROPERTY(QPointF wValue READ wValue NOTIFY wValueChanged)
public:
Data(QObject *parent=Q_NULLPTR);
QPointF wValue() const{
return m_wValue;
}
signals:
void wValueChanged();
private slots:
void wTimeout();
private:
QTimer * m_wTimer;
QPointF m_wValue;
};
#endif // DATA_H
<强> data.cpp 强>
#include "data.h"
void Data::wTimeout(){
int HIGH = 100;
int LOW = 0;
int val = rand() % (HIGH - LOW + 1) + LOW;
m_wValue.setX(m_wValue.x()+1);
m_wValue.setY(val);
emit wValueChanged();
}
Data::Data(QObject *parent):QObject(parent){
m_wTimer = new QTimer(this);
m_wTimer->setInterval((1000 / 5));
connect(m_wTimer, &QTimer::timeout, this, &Data::wTimeout);
m_wTimer->start();
}
<强>的main.cpp 强>
#include "data.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("dataFromCpp", new Data());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
<强> main.qml 强>
import QtQuick 2.8
import QtCharts 2.2
import QtQuick.Window 2.2
Window{
visible: true
width: 640
height: 480
Connections {
target: dataFromCpp
onWValueChanged: {
if(lineSeries1.count > 5)
lineSeries1.remove(0);
lineSeries1.append(dataFromCpp.wValue.x, dataFromCpp.wValue.y)
axisX.min = lineSeries1.at(0).x
axisX.max = lineSeries1.at(lineSeries1.count-1).x
}
}
ChartView {
id: chartView
width: parent.width
height: parent.height
anchors.fill: parent
animationOptions: ChartView.NoAnimation
antialiasing: true
backgroundColor: "#1f1f1f"
ValueAxis {
id: axisY1
min: 0
max: 100
gridVisible: false
color: "#ffffff"
labelsColor: "#ffffff"
labelFormat: "%.0f"
}
ValueAxis {
id: axisX
min: 0
max: 50
gridVisible: false
color: "#ffffff"
labelsColor: "#ffffff"
labelFormat: "%.0f"
tickCount: 5
}
LineSeries {
id: lineSeries1
name: "signal 1"
color: "white"
axisX: axisX
axisY: axisY1
}
}
}
完整示例可在以下link中找到。