从C 推动QML ChartView更新
Push QML ChartView updates from c++
我正在尝试调整QT5.9 QML示波器示例,以将图形数据从C 推出,而不是从QML请求。以下是QML示例示例的相关部分。
datasource.h:
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include <QtCore/QObject>
#include <QtCharts/QAbstractSeries>
QT_BEGIN_NAMESPACE
class QQuickView;
QT_END_NAMESPACE
QT_CHARTS_USE_NAMESPACE
class DataSource : public QObject
{
Q_OBJECT
public:
explicit DataSource(QQuickView *appViewer, QObject *parent = 0);
Q_SIGNALS:
public slots:
void generateData(int type, int rowCount, int colCount);
void update(QAbstractSeries *series);
private:
QQuickView *m_appViewer;
QList<QVector<QPointF> > m_data;
int m_index;
};
#endif // DATASOURCE_H
datasource.cpp:
#include "datasource.h"
#include <QtCharts/QXYSeries>
#include <QtCharts/QAreaSeries>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QtCore/QDebug>
#include <QtCore/QtMath>
QT_CHARTS_USE_NAMESPACE
Q_DECLARE_METATYPE(QAbstractSeries *)
Q_DECLARE_METATYPE(QAbstractAxis *)
DataSource::DataSource(QQuickView *appViewer, QObject *parent) :
QObject(parent),
m_appViewer(appViewer),
m_index(-1)
{
qRegisterMetaType<QAbstractSeries*>();
qRegisterMetaType<QAbstractAxis*>();
generateData(0, 5, 1024);
}
void DataSource::update(QAbstractSeries *series)
{
if (series) {
QXYSeries *xySeries = static_cast<QXYSeries *>(series);
m_index++;
if (m_index > m_data.count() - 1)
m_index = 0;
QVector<QPointF> points = m_data.at(m_index);
// Use replace instead of clear + append, it's optimized for performance
xySeries->replace(points);
}
}
void DataSource::generateData(int type, int rowCount, int colCount)
{
// Remove previous data
m_data.clear();
// Append the new data depending on the type
for (int i(0); i < rowCount; i++) {
QVector<QPointF> points;
points.reserve(colCount);
for (int j(0); j < colCount; j++) {
qreal x(0);
qreal y(0);
switch (type) {
case 0:
// data with sin + random component
y = qSin(3.14159265358979 / 50 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX;
x = j;
break;
case 1:
// linear data
x = j;
y = (qreal) i / 10;
break;
default:
// unknown, do nothing
break;
}
points.append(QPointF(x, y));
}
m_data.append(points);
}
}
main.cpp:
#include <QtWidgets/QApplication>
#include <QtQml/QQmlContext>
#include <QtQuick/QQuickView>
#include <QtQml/QQmlEngine>
#include <QtCore/QDir>
#include "datasource.h"
int main(int argc, char *argv[])
{
// Qt Charts uses Qt Graphics View Framework for drawing, therefore
QApplication must be used.
QApplication app(argc, argv);
QQuickView viewer;
// The following are needed to make examples run without having to install the module
// in desktop environments.
#ifdef Q_OS_WIN
QString extraImportPath(QStringLiteral("%1/../../../../%2"));
#else
QString extraImportPath(QStringLiteral("%1/../../../%2"));
#endif
viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
QString::fromLatin1("qml")));
//QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
viewer.setTitle(QStringLiteral("QML Oscilloscope"));
DataSource dataSource(&viewer);
viewer.rootContext()->setContextProperty("dataSource", &dataSource);
viewer.setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.setColor(QColor("#404040"));
viewer.show();
return app.exec();
}
scopeview.qml:
import QtQuick 2.0
import QtCharts 2.1
ChartView {
id: chartView
animationOptions: ChartView.NoAnimation
theme: ChartView.ChartThemeDark
property bool openGL: true
property bool openGLSupported: true
onOpenGLChanged: {
if (openGLSupported) {
series("signal 1").useOpenGL = openGL;
}
}
Component.onCompleted: {
if (!series("signal 1").useOpenGL) {
openGLSupported = false
openGL = false
}
}
ValueAxis {
id: axisY1
min: -1
max: 4
}
ValueAxis {
id: axisX
min: 0
max: 1024
}
LineSeries {
id: lineSeries1
name: "signal 1"
axisX: axisX
axisY: axisY1
useOpenGL: chartView.openGL
}
Timer {
id: refreshTimer
interval: 1 / 60 * 1000 // 60 Hz
running: true
repeat: true
onTriggered: {
dataSource.update(chartView.series(0));
}
}
}
,我想在QML中使用计时器,而是想在C 类中使用现有的超时将新数据推向QML ChartView。我有两个问题:
- 我将如何实现上面发布的QML示波器示例?
- 哪种格式最适合C 数据来促进这一点?我在想某种QVECTOR;数据将是带有向量索引的整数或浮动。
正如您在评论中所说的,您需要通过一个系列,然后我们创建一种接收该系列并将其保存在C 类的成员中的方法,我们还创建了一个qtimer,我们也这样做以更新间隔:
*。h
public:
Q_INVOKABLE void setSeries(QAbstractSeries *series);
Q_INVOKABLE void setInterval(int interval);
[...]
private:
QXYSeries *mSeries;
QTimer *timer;
[...]
*。cpp
void DataSource::setSeries(QAbstractSeries *series)
{
if (series) {
mSeries = static_cast<QXYSeries *>(series);
}
}
然后我们删除更新参数并使用mseries:
DataSource::DataSource(QQuickView *appViewer, QObject *parent) :
QObject(parent),
m_appViewer(appViewer),
m_index(-1)
{
[...]
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &DataSource::update);
timer->start(1 / 60 * 1000 );
}
void DataSource::update()
{
if (mSeries) {
m_index++;
if (m_index > m_data.count() - 1)
m_index = 0;
QVector<QPointF> points = m_data.at(m_index);
// Use replace instead of clear + append, it's optimized for performance
mSeries->replace(points);
}
}
void DataSource::setInterval(int interval)
{
if(timer){
if(timer->isActive())
timer->stop();
timer->start(interval);
}
}
*。QML
Component.onCompleted: {
dataSource.setSeries(chartView.series(0));
if (!series("signal 1").useOpenGL) {
openGLSupported = false
openGL = false
}
}
[...]
function changeRefreshRate(rate) {
dataSource.setInterval(1 / Number(rate) * 1000);
//refreshTimer.interval = 1 / Number(rate) * 1000;
}
您可以在以下链接中找到完整的示例。
相关文章:
- 从C++本机插件更新Vector3数组
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- cmake更新缓存的变量
- 更新到莫哈韦后出现cmath错误
- OpenMP:并行更新数组总是需要减少数组吗
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 指针没有更新它在void函数内部指向的值
- 如何在c++中获取要更新的值
- 已修改的LinkedList未在文本文件本身中更新
- Qt:当QListView获得新条目时,如何更新QStringList
- 更新的矢量元素不打印
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 如何在ECS框架中更新组件数据和通知系统
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 如果我想在没有更新编译器的情况下使用新功能,该怎么办?
- 如何在 C++11 中查找和更新向量中的一个嵌套结构
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 在 emscripten 网页汇编正在运行期间更新进度条?
- 在运行时使用范围更新结果
- 从C 推动QML ChartView更新