如何在 qml 或 PySide2 中更改 XYSeries 中的所有点? [英] How can I change all the points in an XYSeries in qml or PySide2?

查看:84
本文介绍了如何在 qml 或 PySide2 中更改 XYSeries 中的所有点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 PySide2 和 QML 有点陌生,我真的需要一种方法来一次替换 XYSeries 中的所有点.由于 QML 项没有这样做的函数,我想我必须创建一个自定义类(将从 QtCharts.QXYSeries 继承),实现我需要的函数,然后使用 PySide2.QtQml.qmlRegisterType 注册新类型,但我不知道该怎么做,而且我无法在网上找到答案(或至少是我能理解的答案).

I'm kinda new to PySide2 and QML and I really need a way to replace all the points in an XYSeries at once. Since the QML item does not have a function that does so, I thought I had to create a custom class (that would inherits from QtCharts.QXYSeries), implement the function I need and then register the new type with PySide2.QtQml.qmlRegisterType, but I don't know how that should be done and I haven't been able to find an answer online (or at least one that I could understand).

所以,长话短说,我需要知道是否有办法更改 XYSeries 的所有点以及如何完成(例如,创建自定义类并注册它,访问 Item 声明和在来自 python 的 .qml 文件中并更改其属性等...).
我知道我的问题真的很模糊,但我不知道去哪里看,该怎么做...

So, to cut a long story short, what I need to know is if there's a way to change all the points of an XYSeries and how can it be done (e.g. creating a custom class and registering it, accessing the Item declarend in the .qml file from python and chaning its properties, etc...).
I know my question is really vague but I do not know where to look and what to do...

编辑

我有一个 python 类,它从仪器中获取数据并生成一个 X 和 Y 点数组.由于该阵列由至少 1000 个点组成,并且由于我需要至少 1Hz 的刷新率,因此不可能一次添加一个点(我有一个信号将整个阵列发送到 qml 接口和在那里,目前,我只是清除系列并一次添加一对 XY 对.它有效,但速度太慢了).

I have a python class that acquires data from an instruments and generates an array of X and Y points. Since this arrays are made from at least 1000 points and since I need to have a refresh rate of at least 1Hz, it's impossible to do it adding one point at a time (I have an signal that sends the whole array to the qml interface and there, for the moment, I simply clear the series and add one XY couple at a time. It works but it's too damn slow).

推荐答案

一种可能的解决方案是创建一个允许从 Python 访问 QML 对象的类,在这种情况下,我创建了通过 setContextProperty 导出到 QML 的帮助程序类通过将系列与 qproperty 链接起来.

One possible solution is to create a class that allows access to a QML object from Python, in this case I create the helper class that I export to QML through setContextProperty by linking the series with a qproperty.

ma​​in.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_())

ma​​in.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
    }
}

这篇关于如何在 qml 或 PySide2 中更改 XYSeries 中的所有点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆