qml нарисуйте линейную диаграмму из Qlist с помощью повторителя

#c #qt #qml #lineseries #qchartview

Вопрос:

Я хочу нарисовать график данных датчиков, которые сохраняются в списке вопросов. Я знаю, что доведение данных до уровня qml работает нормально, потому что они правильно выводятся на консоль (см. Код).

Теперь мой вопрос в том, как я могу нарисовать линейную диаграмму на основе этих данных? Я попробовал повторитель и несколько схематичных циклов, но, похоже, ни один из них не работает, и отображается только пустая диаграмма.

Как указано выше, данные работают и регистрируются правильно. Ось тоже правильная, просто линии нет.

Моя самая многообещающая попытка:

 import QtQuick 2.0
import QtCharts 2.3
Item {
    width:400
    height:600
    
    ChartView
    {
    
    width:parent.width
    height:parent.height
    Component.onCompleted:  {
    //Data displayed correctly
        console.log(device.AIN3data.length);
        console.log(device.AIN3data)
    }
    
    ValueAxis {
        id: axisX
        min: 0
        max: device.AIN3data.length
    }
    
    ValueAxis {
        id: axisY
        min: 0
        max: 1000
    }
    LineSeries
    {
        axisX: axisX
        axisY:axisY
    
    
        name: "AIN3"
        Repeater
        {
    
            model: device.AIN3data.length
            XYPoint{x:index;y:device.AIN3data[index]}
            Component.onCompleted: console.log("Repeater")
    
        }
    }
    }
}

 

Ответ №1:

Повторитель используется для создания нескольких элементов, а не для XYPoint. В этом случае лучше создать модель C , экспортировать ее в QML, а затем сопоставить с LineSeries с помощью VXYModelMapper.

 #include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>
#include <QTimer>

#include <random>

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QApplication app(argc, argv);

    QStandardItemModel model(0, 2);

    QTimer timer;
    timer.setInterval(1000);
    QObject::connect(amp;timer, amp;QTimer::timeout, amp;model, [amp;model](){
        static std::default_random_engine e;
        static std::uniform_real_distribution<> dis(0, 1000);
        QStandardItem *xItem = new QStandardItem;
        QStandardItem *yItem = new QStandardItem;
        xItem->setData(model.rowCount(), Qt::DisplayRole);
        yItem->setData(dis(e), Qt::DisplayRole);
        model.appendRow({xItem, yItem});
    });
    timer.start();

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("dataModel", amp;model);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(amp;engine, amp;QQmlApplicationEngine::objectCreated,
                     amp;app, [url](QObject *obj, const QUrl amp;objUrl) {
        if (!obj amp;amp; url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
 
 import QtCharts 2.3
import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ChartView {
        anchors.fill: parent

        ValueAxis {
            id: axisX

            min: 0
            max: lineSeries.count - 1
        }

        ValueAxis {
            id: axisY

            min: 0
            max: 1000
        }

        LineSeries {
            id: lineSeries

            axisX: axisX
            axisY: axisY
        }

    }

    VXYModelMapper {
        id: modelMapper

        model: dataModel
        series: lineSeries
        xColumn: 0
        yColumn: 1
    }

}
 

Комментарии:

1. Нет более простого способа создать линейную диаграмму со всеми данными уже на уровне qml, чем создать модель c ? Пока не знаю, как это интегрировать :я

2. Нашел способ, который работает аналогично примеру с осциллографом. В любом случае, спасибо тебе @eyllanesc

3. @Bl4ckmedia Нет, это простой способ, я не вижу, насколько это сложно, так как код прост.

4. тогда я попробовал по-твоему, и это не сработало. Хотя, возможно, это была моя ошибка.