问题描述
我对 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.
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
}
}
这篇关于如何在 qml 或 PySide2 中更改 XYSeries 中的所有点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!