2017-12-10 21 views
0

データ(現在は上限と下限のしきい値の間に生成された乱数のみ)を収集し、それをQVector(QPointF)にパッケージ化するC++クラスがあります。私はChartViewを含むQMLファイルを持っています。収集したC++データをQML ChartView(LineSeries)にプロットし、C++のデータ収集機能が終了するたびにプロットを更新したいと思います。収集したQVectorをセカンダリのC++クラスに送って、QML ChartViewの更新を実行したいと思います。C++からQMLチャートに接続

以下は、さまざまな関連ファイルの抜粋です。

data.h:

#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 

data.cpp:

#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.h:

#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 

chart.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.cppに:

#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(); 
} 

main.qml:

import QtQuick 2.8 
... 
import QtCharts 2.2 

//I've removed unnecessary QML elements for simplicity 

ChartView { 
    id: chartView 
    width: parent.width 
    height: parent.height 
    anchors.fill: parent 
    margins.bottom: 0 
    margins.top: 0 
    margins.left: 0 
    margins.right: 0 
    animationOptions: ChartView.NoAnimation 
    antialiasing: true 
    legend.visible: false 
    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 
    } 
} 

私の質問:どのように私はchart.cppデータをプロットするためにQMLのLineSeriesがにchart.cppを接続して行う(data.cppから受け取りました) QMLチャートビューでは?

私はQt5.9.2を使用しています。

+0

以前の質問との違いは何ですか? – eyllanesc

+0

こんにちは@eyllanesc!あなたの以前の投稿は大いに助けてくれましたが、main.cppファイルのQQuickViewを使って私の既存のアプリケーションのレイアウトに合っていません。ご覧のとおり、私は昨日お勧め/確認されたQPointF QVectorを構築し、それを外部の.cpp(chart.cpp)に送信し、そのファイルをQMLに接続させたいと思います。オシロスコープの例のQQuickViewメソッド。 – jars121

+0

私はChartクラスが不要だと思います。データを直接送信して更新することができます。 QQuickViewはこの問題とは無関係です。 – eyllanesc

答えて

1

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に見出すことができます。

+0

上記のようにヘッダファイル自体ではなく、data.cppファイルにロジック(m_wTimerおよびwTimeout)を含めるように修正することはできますか?私はchart.cpp/hファイルを削除するのが気に入っていますが、可能であれば、ヘッダーファイルからロジックを抜けておきたいと考えています。 – jars121

+0

ちょうど.cppにコードを移動して、私はすでに行っています、今私の答えを正しいとマークすることを忘れないでください。 – eyllanesc

+0

あなたは天才です、もう一度、ありがとう! – jars121

関連する問題