使用 python 和 QML Oscilloscope 动态绘图效果很好,但相同的程序在树莓派中不起作用,替换功能不起作用
Posted
技术标签:
【中文标题】使用 python 和 QML Oscilloscope 动态绘图效果很好,但相同的程序在树莓派中不起作用,替换功能不起作用【英文标题】:Graphing dynamically with python and QML Oscilloscope works great, but the same program doesn't work in raspberry pi, replace function don't work 【发布时间】:2020-09-02 21:40:42 【问题描述】:我正在使用 Python 运行 Qt QML 应用程序。我正在使用 qt 图表动态绘制值。为此,我编写了与 Qt 文档中的示波器示例类似的代码,除了我使用 Python 而不是 C++。我首先在 QML 中创建了一个线条系列。然后我使用上下文属性向 QML 公开了一个名为“Bridge”的类作为“con”。在名为“Bridge”的类中,我生成了初始数据。然后我在每次计时器计数时更新图表,方法是将系列传递给“桥”类,然后使用替换函数,以便系列快速获取数据,而不是使用清除和追加。
import QtQuick 2.10
import QtQuick.Window 2.5
import QtQuick.Controls 2.4
import QtCharts 2.0
Window
id: window
title: qsTr("QML and Python graphing dynamically")
width: 640
height: 480
color: "#1b480d"
visible: true
Timer
id: miTimer
interval: 1 / 24 * 1000 //update every 200ms
running: true
repeat: true
onTriggered:
con.update_series(chart.series(0))
Label
id: label
x: 298
color: "#f1f3f4"
text: qsTr("Graphin dynamically with python")
anchors.horizontalCenterOffset: 0
anchors.top: parent.top
anchors.topMargin: 10
font.bold: true
font.pointSize: 25
anchors.horizontalCenter: parent.horizontalCenter
ChartView
id: chart
x: 180
y: 90
width: 500
height: 300
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
ValueAxis
id: axisX
min: 0
max: 200
ValueAxis
id: axisY
min: 0
max: 100
Component.onCompleted:
console.log("Se ha iniciado QML\n")
var series = chart.createSeries(ChartView.SeriesTypeLine,"My grafico",axisX,axisY)
con.generateData()
这个 QML 本质上是一个位于中心的图表。在Component.onCompleted
中,我创建了一个使用上下文属性类的线系列,我使用python 对其进行了更新。
# This Python file uses the following encoding: utf-8
import sys
from os.path import abspath, dirname, join
import random
from PySide2.QtCore import QObject, Slot, QPoint
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCharts import QtCharts
from PySide2.QtWidgets import QApplication # <---
class Bridge(QObject):
def __init__(self, parent=None):
super(Bridge, self).__init__(parent)
self.my_data = []
self.index = -1
@Slot(QtCharts.QAbstractSeries)
def update_series(self, series):
self.index += 1
if(self.index > 4):
self.index = 0
series.replace(self.my_data[self.index])
@Slot()
def generateData(self):
my_data = []
for i in range (5):
my_list = []
for j in range(200):
my_list.append(QPoint(j,random.uniform(0,100)))
self.my_data.append(my_list)
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
bridge = Bridge()
# Expose the Python object to QML
context = engine.rootContext()
context.setContextProperty("con", bridge)
#engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))
# Get the path of the current directory, and then add the name
# of the QML file, to load it.
qmlFile = join(dirname(__file__), 'main.qml')
engine.load(abspath(qmlFile))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
效果很好。
问题是完全相同的程序在树莓派 3 中不起作用。错误在series.replace(self.my_data[self.index])
显示类型错误:
replace(double,double,double,double) needs 4 argument(s), 1 given!
为了在树莓派上运行代码,我从以下位置安装了Pyside2
库:
https://forum.qt.io/topic/112813/installing-pyside2-on-raspberry-pi/7
它的版本是PySide2 5.11.2
。
对于 QML 模块,我使用了sudo apt-get install qml-module-xxxxxxx
对于每个需要的库
【问题讨论】:
你能指出你在运行help(QtCharts.QLineSeries.replace)
时得到了什么吗?
我现在试过了。它显示如下: >>>> help(QtCharts.QLineSeries.replace) 关于method_descriptor的帮助:replace(...)
你确定它只是说“method_descriptor: replace(...)”吗?我希望有更多信息,尝试在覆盆子控制台中运行python -c "from PySide2.QtCharts import QtCharts; help(QtCharts.QLineSeries.replace)"
:
基本一样。关于 method_descriptor 的帮助:replace(...) (END) 我也在使用 python3 而不是 python。树莓派有 python 3.7.3。此外,我进一步检查并意识到 append 函数也会发生同样的情况。 TypeError: append(double,double) 需要 2 个参数,1 个给定!相同的代码在桌面上运行良好。
试试我的解决方案
【参考方案1】:
一种可能的解决方案是替换
series.replace(self.my_data[self.index])
与:
series.clear()
for p in self.my_data[self.index]:
series.append(p.x(), p.y())
【讨论】:
这个变通方法使代码在树莓派上运行。现在我可以在树莓派 3 上动态更新图表了。非常感谢您的帮助。现在,我尝试使用 replace 而不是 clear + append 的原因是因为根据 Qt 文档,替换要快得多。在桌面上,我测量了计时器触发之间的时间。使用替换花费的时间更少。我在 pi 上做了同样的事情,列出了 200 个元素,我可以让它在计时器触发之间至少间隔 130 毫秒。也许如果我在 pi4 上运行它,它会运行得更快。我不知道为什么这些 pyside2 函数在 pi 上不起作用。 @ManuelAnatoliyArciaSalmeron 1) 问题不在于 RPI,而在于您使用的 PySide2 非常旧版本。我安装了 PySide2 5.11.2 并且在我的桌面上遇到了同样的错误,可能未来版本的 raspbian(或您使用的发行版)将提供更新的版本。 2)它说的是正确的:替换比清除+附加更快。 3)如果我的回答对您有帮助,请不要忘记标记为正确,如果您不知道该怎么做,请查看tour 是的,我确实使用 Raspbian。你知道是否有办法为树莓派安装更新的 PySide2 或者我交叉编译会更好(必须去学习如何做到这一点)。 @ManuelAnatoliyArciaSalmeron pip 提供的二进制文件不适用于 ARM 架构,因此它们对 RPI 无效,因此如果您想要更新版本的 PySide2,您必须手动编译 PySide2(或者使用交叉编译器或其他方式)以上是关于使用 python 和 QML Oscilloscope 动态绘图效果很好,但相同的程序在树莓派中不起作用,替换功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章