Как я могу изменить все точки в XYSeries в qml или PySide2? - PullRequest
1 голос
/ 20 марта 2019

Я новичок в PySide2 и QML, и мне действительно нужен способ заменить все точки в XYSeries сразу.Поскольку элемент QML не имеет функции, которая делает это, я подумал, что мне нужно создать собственный класс (который будет наследоваться от QtCharts.QXYSeries), реализовать нужную мне функцию и затем зарегистрировать новый тип с помощью PySide2.QtQml.qmlRegisterType,но я не знаю, как это сделать, и я не смог найти ответ в Интернете (или хотя бы один, который мог бы понять).

Итак, вкратце, мне нужно знать, есть ли способ изменить все точки XYSeries и как это можно сделать (например, создать собственный класс и зарегистрировать его, получить доступ кОбъявление элемента в файле .qml от python и изменение его свойств и т. д.).
Я знаю, что мой вопрос действительно расплывчатый, но я не знаю, где искать и что делать ...

РЕДАКТИРОВАТЬ

У меня есть класс Python, который получает данные от инструментов и генерирует массив точек X и Y.Поскольку эти массивы состоят как минимум из 1000 точек, а так как мне нужно иметь частоту обновления не менее 1 Гц, это невозможно сделать, добавляя по одной точке за раз (у меня есть сигнал, который отправляет весь массив в интерфейс qml итам, на данный момент, я просто очищаю серию и добавляю одну пару XY за раз. Это работает, но это слишком чертовски медленно).

1 Ответ

1 голос
/ 20 марта 2019

Одним из возможных решений является создание класса, обеспечивающего доступ к объекту QML из Python, в этом случае я создаю вспомогательный класс, который я экспортирую в QML через setContextProperty, связывая ряд с помощью qproperty.

main.py

import random
from PySide2 import QtCore, QtWidgets, QtQml
from PySide2.QtCharts import QtCharts

class Helper(QtCore.QObject):
    serieChanged = QtCore.Signal()

    def __init__(self, parent=None):
        super(Helper, self).__init__(parent)
        self._serie = None

    def serie(self):
        return self._serie

    def setSerie(self, serie):
        if self._serie == serie:
            return
        self._serie = serie
        self.serieChanged.emit()

    serie = QtCore.Property(QtCharts.QXYSeries, fget=serie, fset=setSerie, notify=serieChanged)

    @QtCore.Slot(list)
    def replace_points(self, points):
        if self._serie is not None:
            self._serie.replace(points)

class Provider(QtCore.QObject):
    pointsChanged = QtCore.Signal(list)

    def __init__(self, parent=None):
        super(Provider, self).__init__(parent)
        timer = QtCore.QTimer(
            self, 
            interval=100,
            timeout=self.generate_points
        )
        timer.start()

    @QtCore.Slot()
    def generate_points(self):
        points = []
        for i in range(101):
            point = QtCore.QPointF(i, random.uniform(-10, 10))
            points.append(point)
        self.pointsChanged.emit(points)

if __name__ == '__main__':
    import os
    import sys
    app = QtWidgets.QApplication(sys.argv)
    helper = Helper()
    provider = Provider()
    provider.pointsChanged.connect(helper.replace_points)
    engine = QtQml.QQmlApplicationEngine()
    engine.rootContext().setContextProperty("helper", helper)
    file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(file))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtCharts 2.3

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    ChartView{
        anchors.fill: parent
        LineSeries{
            id: serie
            axisX: axisX
            axisY: axisY
        }
        ValueAxis {
            id: axisX
            min: 0
            max: 100
        }

        ValueAxis {
            id: axisY
            min: -10
            max: 10
        }
        Component.onCompleted: helper.serie = serie
    }
}
...